3

我经常处理这种形式的对象:

v <- list(one = c(a = 1, b = 2, c = 3), two = c(a = 10, b = 20, d = 30, c = 40))

我想通过元素名称外部连接这些向量,以获得:

  index value.x value.y
1     a       1      10
2     b       2      20
3     c       3      40
4     d      NA      30

我已经编写了代码来做到这一点。简而言之,将向量转换为数据帧并通过连续合并减少。但我想知道我是否一直在重新发明轮子,并且包中或 R 基础中包含一些可能优化的功能。这似乎是一个很常见的任务。

4

3 回答 3

2

不确定这是否比您的方法更简单,但您可以使用reshape2,lapply和 as.list。我认为melt`dcast

library(reshape2)
dcast(melt(lapply(v, as.list)), L2 ~L1)
##   L2 one two
## 1  a   1  10
## 2  b   2  20
## 3  c   3  40
## 4  d  NA  30
于 2012-09-06T03:50:26.527 回答
2

以下是基本 R 中的两个选项。它们需要将您list转换为data.frame第一个。

v2 <- data.frame(do.call(rbind, 
                         strsplit(names(unlist(v)), "\\.")), 
                 unlist(v))
names(v2) <- c("time", "id", "value")
xtabs(value ~ id + time, v2)
#     time
#  id  one two
#    a   1  10
#    b   2  20
#    c   3  40
#    d   0  30
reshape(v2, direction="wide", idvar="id", timevar="time")
#       id value.one value.two
# one.a  a         1        10
# one.b  b         2        20
# one.c  c         3        40
# two.d  d        NA        30

我不知道有一种更直接的方法来拆分namesusing 产生的结果unlist,但是一旦完成,您尝试进行的操作就会变得容易得多。

分配新名称以使输出更“整洁”。

于 2012-09-06T04:02:59.327 回答
1

这是一个基本解决方案:

> do.call( merge,  list(v[[1]], v[[2]], by="row.names", all=TRUE))
  Row.names  x  y
1         a  1 10
2         b  2 20
3         c  3 40
4         d NA 30

如需更多长度 >2 的列表,您可以使用as.data.frame.table将命名向量转换为两列data.frame

> v <- list(one = c(a = 1, b = 2, c = 3), 
           two = c(a = 10, b = 20, d = 30, c = 40), 
           three = c(a = 1, b = 2, c = 3))
> setNames(Reduce(function(x,y) {
        merge(x,y,all=T, by ='Var1')},lapply(v, as.data.frame.table)),
         c('index', names(v)))

  index one two three
1     a   1  10     1
2     b   2  20     2
3     c   3  40     3
4     d  NA  30    NA
于 2012-09-06T04:16:34.097 回答