3

我有一个 data.frames 列表,每个 data.frames 中有多个列。每个 data.frame 具有相同的结构。此外,我还有另一个包含多个 data.frames 的列表。

假设这是两个列表:

firstlist <- list(a=data.frame(AA=5:1,
                        BB=1:5),
           b=data.frame(AA=5:1,
                        BB=1:5),
           c=data.frame(AA=5:1,
                        BB=1:5))
secondlist <- list(a=data.frame(AA=1:10,
                        BB=c(0,0,1,0,0,1,1,0,0,0)),
           b=data.frame(AA=1:10,
                        BB=c(0,1,0,0,0,0,1,0,0,0)),
           c=data.frame(AA=1:10,
                        BB=c(1,0,0,0,0,1,1,0,0,0)))

现在我想将 CC 列添加到 firstlist 中的所有 data.frames 中,并根据 secondlist 中 BB 列中的值填充它们。

问题是:我需要检查 firstlist 中 AA 或 BB 中的行是否包含 secondlist 中 AA 的值,并用 secondlist 中 BB 的值填充 firstlist 中的新列 CC。

上面示例数据的预期结果将是:

> firstlist
$a
     AA BB CC
  1  5  1  0
  2  4  2  0
  3  3  3  1
  4  2  4  0
  5  1  5  0

$b
    AA BB CC
  1  5  1  0
  2  4  2  1
  3  3  3  0
  4  2  4  1
  5  1  5  0

$c
    AA BB CC
  1  5  1  1
  2  4  2  0
  3  3  3  0
  4  2  4  0
  5  1  5  1

我需要使用 For 循环还是有其他方法?

更新:请参阅Thell 的布尔数据解决方案和eddie 的所有数据类型解决方案。

先感谢您!

4

3 回答 3

2

这是另一种相对较短的方式(假设BBinsecondlist是二进制的(只有 0 和另一个值):

lapply(seq_along(firstlist), function(ix) {
    tt <- secondlist[[ix]][secondlist[[ix]]$BB != 0, ]
    transform(firstlist[[ix]], CC = 1 * (firstlist[[ix]]$AA %in% tt$AA | 
        firstlist[[ix]]$BB %in% tt$AA))
})
于 2013-06-19T19:34:19.543 回答
2

如果 CC 是真正的布尔值...

f <- function(a,b) cbind( a, CC=b$BB[ match( a$AA, b$AA ) ] |
                                b$BB[ match( a$BB, b$AA ) ]   )
mapply( f, firstlist, secondlist, SIMPLIFY=F )

直截了当,快速,并保持名字......

示例与 lapply 版本的基准测试::

Unit: milliseconds
          expr       min       lq   median       uq      max neval
   this mapply  1.726471 1.840671 1.870504 1.939473 13.88875   100
 Arun's lapply  2.930061 3.048110 3.134402 3.209786 14.61630   100
于 2013-06-19T21:14:28.070 回答
1
lapply(seq_along(firstlist),
       function(i) {
         d.1 = merge(firstlist[[i]], secondlist[[i]], by = "AA", sort = FALSE)
         names(d.1) = c("AA", "BB", "CC")
         d.2 = suppressWarnings(merge(firstlist[[i]], secondlist[[i]], by.x = "BB", by.y = "AA", sort = FALSE))
         names(d.2) = c("BB", "AA", "CC")
         d.1$CC = 0 + (d.1$CC | d.2$CC)
         d.1
       })

您可能想要重命名上面的列而不是禁止显示警告。

于 2013-06-19T19:02:54.017 回答