lapply从列表中提取行

时间:2015-10-19 14:49:23

标签: r subset lapply

我有以下问题: 我有一个列表(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与子集函数结合起来,但这对我不起作用。 谢谢你的帮助!

3 个答案:

答案 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创建一个函数。我们使用listrbindlist元素进行搜索,按&#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