【问题标题】:lapply to extract rows from listlapply 从列表中提取行
【发布时间】:2015-10-19 14:49:22
【问题描述】:

我有以下问题: 我有一个包含两个部分和每个 4 个相同变量的列表(L1)。 变量 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 与子集函数结合起来,但这对我不起作用。 感谢您的帮助!

【问题讨论】:

  • 编写你自己的函数foo,它接受一个data.frame df和一个V3的值(我们称之为v)。所以写foo(df, v)返回你想要的。然后,只需将其应用于列表:lapply(L1, FUN=foo, 3)。注意这里的3是作为foo的第二个参数传递的。

标签: r subset lapply


【解决方案1】:

这应该可行。第一个命令返回一个列表,第二个命令将其转换为数据框。如果值不在数据中,则返回 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]])

【讨论】:

  • 感谢您的回答!这很好用。还有一个问题:当找不到值时,如何实现函数返回 NA?
  • 我会把答案放在我原来的答案中
  • 非常感谢您的帮助。你的解决方案解决了我的问题,我学到了很多!
【解决方案2】:

我们可以使用data.table 创建一个函数。我们将list 元素与rbindlist 绑定,按'V4' 分组,if 'V3' 不等于给定值,我们返回NA 元素(.SD[.N+1])或者返回数据子集.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

【讨论】:

  • 感谢您的回答和帮助!我使用了tello的答案。但我也会尝试你的解决方案。谢谢!
  • @Carlos 没问题。很高兴为您提供帮助。
【解决方案3】:

你也可以用 dplyr 绑定行

list(a = a, b = b) %>%
  bind_rows(.id = "source") %>%
  filter(V2 == 2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2022-10-26
    • 2017-03-01
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    相关资源
    最近更新 更多