我想根据常见的id变量合并两个数据帧列表,请考虑以下示例
set.seed(1)
mylist1=data.frame(id=sample(paste0("id",sample(1:5,10,T))),var1=sample(letters[1:26],10,T),stringsAsFactors=F);mylist1=split(mylist1,mylist1$id)
set.seed(2)
mylist2=data.frame(id=sample(paste0("id",sample(1:5,10,T))),var2=sample(LETTERS[1:26],10,T),stringsAsFactors=F);mylist2=split(mylist2,mylist2$id)
mylist1
# $id1
# id var1
# id1 d
#
# $id2
# id var1
# id2 f
# id2 g
# id2 w
# etc.
mylist2
# $id1
# id var2
# id1 V
# id1 D
# id1 J
#
# $id3
# id var2
# id3 K
# id3 J
# id3 Z
# etc.
生成的数据框列表应如下所示
# $id1
# id var1 var2
# id1 d V
# id1 d D
# id1 d J
# $id2
# id var1 var2
# id2 f NA
# id2 g NA
# id2 w NA
# etc.
你知道我该怎么做吗?
答案 0 :(得分:2)
我们可以使用Map
来执行此操作。从示例数据集中可以清楚地看出,只有一些list
个元素是共同的(基于列表元素的名称)。
我们的第一步是使用unique
获取每个list
中的所有union
个名称。我们将第一个('lst1')和第二list
('lst2')与这些名称('nm1')进行子集化。如果缺少元素,则该位置将为NULL
元素。
nm1 <- union(names(mylist1), names(mylist2))
lst1 <- mylist1[nm1]
lst2 <- mylist2[nm1]
现在,我们通过为该位置创建“data.frame”来更改每个NULL
中的list
值。我们可以使用if/else
在lapply
循环中执行此操作。
lst1 <- lapply(lst1, function(x) if(is.null(x))
data.frame(id=NA, var1=NA) else x)
lst2 <- lapply(lst2, function(x) if(is.null(x))
data.frame(id=NA, var2=NA) else x)
之后,我们可以使用merge
lists
Map
两个lists
。 merge
的相应元素为MoreArgs
d。我们可以使用merge
来指定Map(merge, lst1, lst2,MoreArgs=list(by='id', all=TRUE))
#$id1
# id var1 var2
#1 id1 d V
#2 id1 d D
#3 id1 d J
#$id2
# id var1 var2
#1 id2 f NA
#2 id2 g NA
#3 id2 w NA
#4 <NA> <NA> NA
#$id3
# id var1 var2
#1 id3 y K
#2 id3 y J
#3 id3 y Z
#$id4
# id var1 var2
#1 id4 a D
#2 id4 i D
#$id5
# id var1 var2
#1 id5 q R
#2 id5 q M
#3 id5 q D
#4 id5 k R
#5 id5 k M
#6 id5 k D
#7 id5 j R
#8 id5 j M
#9 id5 j D
可能需要的额外参数,而不是使用匿名函数。
var players = [
{
id: 1,
name: 'Player 1'
},
{
id: 2,
name: 'Player 2'
}
];