2

我有两个清单。列表中的每个组件都是一个数据框。这两个列表是对称的。它们都包含 2006-2012 年的数据框,只是主题不同。我想“水平”合并数据框(即第一个列表中的 2006 年与第二个列表中的 2006 年的数据框,依此类推)获得第三个数据框列表。我试图弄清楚如何用 lapply 做到这一点,但肯定有一些我不了解该功能的地方。

能否请你帮忙?

谢谢你。

4

3 回答 3

3

l3这段代码中的东西,你的意思是?

DT1 = data.frame(A=1:3,B=letters[1:3])
DT2 = data.frame(A=4:5,B=letters[4:5])
l1 = list(DT1,DT2)
DT1 = data.frame(A=1:3,C=letters[7:9])
DT2 = data.frame(A=4:5,C=letters[11:12])
l2 = list(DT1,DT2)

l3 <- vector(mode = "list", length = length(l1))
for ( i in 1:length(l1))
{
l3[[i]]   <- merge(l2[[i]],l1[[i]], by = "A")
}
于 2013-11-05T17:23:39.960 回答
1

也许这样的事情就是你所追求的?

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(),但这应该会让您走上正确的道路。这显然假设您已经为列表命名,并且这些名称在 和 之间是一致l1l2

编辑以添加更多上下文

有一些关键假设可以使这项工作。这些假设是:

  1. 您的列表对象有names
  2. names在每个列表中的列表之间是一致的

那么,names我指的是什么?如果您查看有关我定义位置的代码l1,您会看到x2006 = df1x2007 = df2。我在该列表中定义了两个对象,df1df2具有两个名称x2006x2007.

您可以通过询问以下内容来检查列表的名称names()

names(l1)
####
[1] "x2006" "x2007"

另一个关键假设是您可以使用该[[函数按名称索引列表中的对象。例如:

l1[["x2006"]]
####
  year x
1 2006 1
2 2006 2
3 2006 3

所以我们对lapply函数所做的就是遍历 的名称l1,定义一个匿名函数,然后使用该[[函数来索引两个列表对象l1l2. 我们目前使用cbindas 函数,但您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
于 2013-11-05T17:26:26.513 回答
1

mapply在这里也可能有用。

这是您可能要求的第三种解释:

一些样本数据:

DT1 <- data.frame(A=1:3, B=letters[1:3])
DT2 <- data.frame(A=4:5, C=letters[4:5])
l1 <- list(DT1,DT2)
DT1 <- data.frame(A=1:3, B=letters[7:9])
DT2 <- data.frame(A=4:5, C=letters[11:12])
l2 = list(DT1,DT2)

mergemapply

mapply(FUN=function(x, y) merge(x, y, by="A"), 
       l1, l2, SIMPLIFY=FALSE)
# [[1]]
#   A B.x B.y
# 1 1   a   g
# 2 2   b   h
# 3 3   c   i
# 
# [[2]]
#   A C.x C.y
# 1 4   d   k
# 2 5   e   l

以供参考....

这是@Chase 对您的问题的解释mapply

mapply(cbind, l1, l2, SIMPLIFY=FALSE)
# $x2006
#   year x year x
# 1 2006 1 2006 7
# 2 2006 2 2006 8
# 3 2006 3 2006 9
# 
# $x2007
#   year x year  x
# 1 2007 4 2007 10
# 2 2007 5 2007 11
# 3 2007 6 2007 12

这是@Codoremifa 对您的问题的解释mapply

mapply(FUN=function(x, y) merge(x, y), 
       l1, l2, SIMPLIFY=FALSE)
# [[1]]
#   A B C
# 1 1 a g
# 2 2 b h
# 3 3 c i
# 
# [[2]]
#   A B C
# 1 4 d k
# 2 5 e l

如果您发布一些示例数据和预期的输出,这样会更有帮助,这样您就可以减少对您要做什么的猜测:-)

于 2013-11-05T18:13:54.253 回答