我有以下问题: 我有一个列表(L1),包含两个部分和每个4个相同的变量。 变量4也是列表部分的名称。例如$ a = a
a <- data.frame(V1=c("a","b","c"), V2=c(4,7,9), V3=1:3, V4=c("a","a","a"))
b <- data.frame(V1=c("d","e","f"), V2=c(10,14,16), V3=1:3, V4=c("b","b","b"))
L1 <- list(a=a, b=b)
L1
$a
V1 V2 V3 V4
a 4 1 a
b 7 2 a
c 9 3 a
$b
V1 V2 V3 V4
d 10 1 b
e 14 2 b
f 16 3 b
我想用V3 == 2提取列表每个部分的行。如果列表中没有行,则该值应使用NA提取V1至V3,并且V4应包含列表部分的名称。
在示例中,结果应如下所示:
V1 V2 V3 V4
b 7 2 a
e 14 2 b
如果我选择一个值,例如V3 == 4然后我的结果应如下所示:
V1 V2 V3 V4
<NA> <NA> <NA> a
<NA> <NA> <NA> b
我可以用。提取列
unlist(lapply(L1, "[",3))
但我无法弄清楚如何提取变量中具有特定值的行。
我也尝试将lapply与子集函数结合起来,但这对我不起作用。
谢谢你的帮助!
答案 0 :(得分:2)
这应该有效。第一个命令返回一个列表,第二个命令将其转换为数据帧。如果该值不在数据中,则返回NA(对于列表)或一行NA(对于df)。
l <- lapply(L1, function(x) {i <- which(x$V3 == 2)
if (length(i) > 0) x[i, ]
else NA })
df <- rbind(l[[1]], l[[2]])
答案 1 :(得分:2)
您也可以使用dplyr
绑定__list(a = a, b = b) %>%
bind_rows(.id = "source") %>%
filter(V2 == 2)
答案 2 :(得分:2)
我们可以使用data.table
创建一个函数。我们使用list
对rbindlist
元素进行搜索,按&#39; V4&#39;,if
分组&#39; V3&#39;不等于给定值,我们返回NA元素(.SD[.N+1]
)或者返回Data.table(.SD[tmp]
)的子集。
library(data.table)
f1 <- function(lst, val){
rbindlist(lst)[, {tmp <- V3==val
if(!any(tmp)) .SD[.N+1]
else .SD[tmp]},
by = V4][, names(lst[[1]]), with=FALSE]
}
f1(L1, 4)
# V1 V2 V3 V4
#1: NA NA NA a
#2: NA NA NA b
f1(L1, 3)
# V1 V2 V3 V4
#1: c 9 3 a
#2: f 16 3 b
f1(L1, 2)
# V1 V2 V3 V4
#1: b 7 2 a
#2: e 14 2 b