也许which()
和的组合%in%
可以帮助您:
dat[which(rownames(dat) %in% c("row.name13")) + c(-1, 1), ]
# col1 col2 col3 col4
# row.name12 A 29 x y
# row.name14 A 77 x y
在上面,我们试图识别“dat”中的哪些行名是“row.name13”(使用which()
),并+ c(-1, 1)
告诉 R 返回之前的行和之后的行。如果您想包含该行,您可以执行类似+ c(-1:1)
.
要获取行的范围,请将逗号切换为冒号:
dat[which(rownames(dat) %in% c("row.name13")) + c(-1:1), ]
# col1 col2 col3 col4
# row.name12 A 29 x y
# row.name13 B 17 x y
# row.name14 A 77 x y
更新
匹配一个列表有点棘手,但不用考虑太多,这里有一种可能性:
myRows <- c("row.name12", "row.name13")
rowRanges <- lapply(which(rownames(dat) %in% myRows), function(x) x + c(-1:1))
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 2 3 4
#
lapply(rowRanges, function(x) dat[x, ])
# [[1]]
# col1 col2 col3 col4
# row.name11 A 23 x y
# row.name12 A 29 x y
# row.name13 B 17 x y
#
# [[2]]
# col1 col2 col3 col4
# row.name12 A 29 x y
# row.name13 B 17 x y
# row.name14 A 77 x y
这输出 a list
of data.frame
s 可能很方便,因为您可能有重复的行(如本例中所示)。
更新 2:使用grep
是否更合适
这是您问题的一种变体,使用which()
...%in%
方法解决起来不太方便。
set.seed(1)
dat1 <- data.frame(ID = 1:25, V1 = sample(100, 25, replace = TRUE))
rownames(dat1) <- paste("rowname", sample(apply(combn(LETTERS[1:4], 2),
2, paste, collapse = ""),
25, replace = TRUE),
sprintf("%02d", 1:25), sep = ".")
head(dat1)
# ID V1
# rowname.AD.01 1 27
# rowname.AB.02 2 38
# rowname.AD.03 3 58
# rowname.CD.04 4 91
# rowname.AD.05 5 21
# rowname.AD.06 6 90
现在,假设您想用AB
and标识行AC
,但您没有数字后缀的列表。
这是一个可以在这种情况下使用的小功能。它从@Spacedman 借了一点,以确保返回的行在数据范围内(根据@flodel 的建议)。
getMyRows <- function(data, matches, range) {
rowMatches = lapply(unlist(lapply(matches, function(x)
grep(x, rownames(data)))), function(y) y + range)
rowMatches = lapply(rowMatches, function(x) x[x > 0 & x <= nrow(data)])
lapply(rowMatches, function(x) data[x, ])
}
您可以按如下方式使用它(但我不会在这里打印结果)。首先,指定数据集,然后是要匹配的模式,然后是范围(在本例中,前三行和后四行)。
getMyRows(dat1, c("AB", "AC"), -3:4)
将其应用于前面的匹配row.name12
and示例row.name13
,您可以按如下方式使用它:getMyRows(dat, c(12, 13), -1:1)
.
您还可以修改该函数以使其更通用(例如,指定与列名而不是行名匹配)。