How to slice a dataframe by selecting a range of columns and rows based on names and not indexes?

醉酒当歌 提交于 2019-12-05 06:34:50

You can use which() with rownames:

subset(df[which(rownames(df)=='r3'):which(rownames(df)=='r5'),], select=c1:c4)


   c1 c2 c3 c4
r3  3  4  5  6
r4  4  5  6  7
r5  5  6  7  8

You can write a function that will kinda give you the same behavior

'%:%' <- function(object, range) {
  FUN <- if (!is.null(dim(object))) {
    if (is.matrix(object)) colnames else names
  } else identity
  wh <- if (is.numeric(range)) range else which(FUN(object) %in% range)
  FUN(object)[seq(wh[1], wh[2])]
}

df <- data.frame(c1=1:6, c2=2:7, c3=3:8, c4=4:9, c5=5:10, c6=6:11)
rownames(df) <- c('r1', 'r2', 'r3', 'r4', 'r5', 'r6')

Use it like

df %:% c('c2', 'c4')
# [1] "c2" "c3" "c4"

rownames(df) %:% c('r2', 'r4')
# [1] "r2" "r3" "r4"

For your question

df[rownames(df) %:% c('r3', 'r5'), df %:% c('c1', 'c5')]
#    c1 c2 c3 c4 c5
# r3  3  4  5  6  7
# r4  4  5  6  7  8
# r5  5  6  7  8  9

Use match to find the position of specific row names.

df[match("r3", rownames(df)):match("r5", rownames(df)), match("c1", colnames(df)):match("c4", colnames(df))]

   c1 c2 c3 c4
r3  3  4  5  6
r4  4  5  6  7
r5  5  6  7  8
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!