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