考虑任何数据帧
col1 col2 col3 col4
row.name11 A 23 x y
row.name12 A 29 x y
row.name13 B 17 x y
row.name14 A 77 x y
Run Code Online (Sandbox Code Playgroud)
我有一个rownlist列表,我想从这个数据帧返回.假设我在列表中有row.name12和row.name13.我可以轻松地从数据帧返回这些行.但我也希望在这些行上方返回4行和4行.这意味着我想从row.name8返回到row.name17.我认为它类似于grep -A -Bshell.
可能的解决方案 - 有没有办法按行名返回行号?因为如果我有行号,我可以轻松地减去4并在行号中添加4并返回行.
Note: Here rownames are just examples. Rownames could be anything like RED, BLUE, BLACK, etc.
试试看:
extract.with.context <- function(x, rows, after = 0, before = 0) {
match.idx <- which(rownames(x) %in% rows)
span <- seq(from = -before, to = after)
extend.idx <- c(outer(match.idx, span, `+`))
extend.idx <- Filter(function(i) i > 0 & i <= nrow(x), extend.idx)
extend.idx <- sort(unique(extend.idx))
return(x[extend.idx, , drop = FALSE])
}
dat <- data.frame(x = 1:26, row.names = letters)
extract.with.context(dat, c("a", "b", "j", "y"), after = 3, before = 1)
# x
# a 1
# b 2
# c 3
# d 4
# e 5
# i 9
# j 10
# k 11
# l 12
# m 13
# x 24
# y 25
# z 26
Run Code Online (Sandbox Code Playgroud)
也许相结合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
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们试图确定“ 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
Run Code Online (Sandbox Code Playgroud)
匹配列表有些棘手,但是如果您考虑得不多,则有可能:
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
Run Code Online (Sandbox Code Playgroud)
这种输出list的data.frameS的可能是方便,因为你可能有重复的行(因为有在这个例子中)。
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
Run Code Online (Sandbox Code Playgroud)
现在,假设您想用AB和标识行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, ])
}
Run Code Online (Sandbox Code Playgroud)
您可以按以下方式使用它(但我不会在此处打印结果)。首先,指定数据集,然后指定要匹配的模式,然后指定范围(在此示例中,前三行,后四行)。
getMyRows(dat1, c("AB", "AC"), -3:4)
Run Code Online (Sandbox Code Playgroud)
将其应用于前面的row.name12and 匹配示例row.name13,您可以按以下方式使用它:getMyRows(dat, c(12, 13), -1:1)。
您还可以修改该函数以使其更通用(例如,指定使用列而不是行名进行匹配)。
| 归档时间: |
|
| 查看次数: |
5237 次 |
| 最近记录: |