lapply 从列表中提取行
lapply to extract rows from list
我有以下问题:
我有一个包含两部分的列表 (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 列表的每个部分的行。如果列表中没有具有此值的行,V1 到 V3 应使用 NA 提取,V4 应包含列表部分的名称。
在示例中,结果应如下所示:
V1 V2 V3 V4
b 7 2 a
e 14 2 b
如果我 select 一个值,例如V3==4 那么我的结果应该是这样的:
V1 V2 V3 V4
<NA> <NA> <NA> a
<NA> <NA> <NA> b
我可以提取列
unlist(lapply(L1, "[",3))
但我不知道如何提取变量中具有特定值的行。
我还尝试将 lapply 与 subset 函数结合使用,但这对我不起作用。
感谢您的帮助!
这应该有效。第一个命令 returns 一个列表,第二个命令将其转换为数据框。如果该值不在数据中,则它 returns 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]])
您还可以 bind_rows 使用 dplyr
list(a = a, b = b) %>%
bind_rows(.id = "source") %>%
filter(V2 == 2)
我们可以使用 data.table
创建一个函数。我们将list
元素与rbindlist
绑定,按'V4'分组,if
'V3'不等于给定值,我们return NA 元素 (.SD[.N+1]
) 或 return 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
我有以下问题: 我有一个包含两部分的列表 (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 列表的每个部分的行。如果列表中没有具有此值的行,V1 到 V3 应使用 NA 提取,V4 应包含列表部分的名称。
在示例中,结果应如下所示:
V1 V2 V3 V4
b 7 2 a
e 14 2 b
如果我 select 一个值,例如V3==4 那么我的结果应该是这样的:
V1 V2 V3 V4
<NA> <NA> <NA> a
<NA> <NA> <NA> b
我可以提取列
unlist(lapply(L1, "[",3))
但我不知道如何提取变量中具有特定值的行。
我还尝试将 lapply 与 subset 函数结合使用,但这对我不起作用。
感谢您的帮助!
这应该有效。第一个命令 returns 一个列表,第二个命令将其转换为数据框。如果该值不在数据中,则它 returns 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]])
您还可以 bind_rows 使用 dplyr
list(a = a, b = b) %>%
bind_rows(.id = "source") %>%
filter(V2 == 2)
我们可以使用 data.table
创建一个函数。我们将list
元素与rbindlist
绑定,按'V4'分组,if
'V3'不等于给定值,我们return NA 元素 (.SD[.N+1]
) 或 return 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