也许这就是你所追求的?
df1 <- data.frame(year = 2006, x = 1:3)
df2 <- data.frame(year = 2007, x = 4:6)
df3 <- data.frame(year = 2006, x = 7:9)
df4 <- data.frame(year = 2007, x = 10:12)
l1 <- list(x2006 = df1, x2007 = df2)
l2 <- list(x2006 = df3, x2007 = df4)
lapply(names(l1), function(x) cbind(l1[[x]], l2[[x]]))
####
[[1]]
year x year x
1 2006 1 2006 7
2 2006 2 2006 8
3 2006 3 2006 9
[[2]]
year x year x
1 2007 4 2007 10
2 2007 5 2007 11
3 2007 6 2007 12
可能还有比cbind() 更合适的其他功能,例如merge(),但这应该会让您走上正确的道路。这显然假设您已经为列表命名,并且这些名称在 l1 和 l2 之间是一致的。
已编辑以添加更多上下文
有几个关键假设可以使这项工作奏效。这些假设是:
- 您的列表对象有
names
- 每个列表中的
names在列表之间是一致的
那么,我指的是什么names?如果您查看关于我在哪里定义l1 的代码,您会看到x2006 = df1 和x2007 = df2。我在该列表中定义了两个对象,df1 和 df2 有两个名称 x2006 和 x2007。
您可以通过询问names()来查看列表名称:
names(l1)
####
[1] "x2006" "x2007"
另一个关键假设是您可以使用[[ 函数按名称索引列表中的对象。例如:
l1[["x2006"]]
####
year x
1 2006 1
2 2006 2
3 2006 3
所以我们对lapply 函数所做的就是遍历l1 的名称,定义一个匿名函数,然后使用[[ 函数来索引两个列表对象@987654343 @ 和 l2。我们目前使用cbind 作为函数,但您可以用几乎任何其他函数替换cbind。
正如我上面提到的,这假设names 在两个或多个列表对象之间是相同的。例如,这不起作用:
#change the names of the l2 list
names(l2) <- c("foo", "bar")
lapply(names(l1), function(x) cbind(l1[[x]], l2[[x]]))
####
Error in data.frame(..., check.names = FALSE) :
arguments imply differing number of rows: 3, 0
names 但不必处于相同的顺序。这就是 [[ 函数的好处所在。也就是说:
#Fix names on l2 again
names(l2) <- c("x2006", "x2007")
l2reverse <- list(x2007 = df4, x2006 = df3)
all.equal(
lapply(names(l1), function(x) cbind(l1[[x]], l2[[x]])),
lapply(names(l1), function(x) cbind(l1[[x]], l2reverse[[x]]))
)
####
[1] TRUE