考虑到数据帧的顺序,如何匹配R中两个列表的元素

时间:2013-11-21 02:13:40

标签: r

大家好我正在处理R中的两个数据帧列表。我想解决一个小问题,我在每个列表中有相同数量的数据帧,每个数据帧都处于相同的位置。我的两个列表的dput版本是下一个:

list1=structure(list(a1 = structure(list(a1 = c("001", "002", "003"
), b1 = c(12, 13, 12)), .Names = c("a1", "b1"), row.names = c(NA, 
-3L), class = "data.frame"), a2 = structure(list(a1 = c("005", 
"006", "009"), b1 = c(12, 16, 16)), .Names = c("a1", "b1"), row.names = c(NA, 
-3L), class = "data.frame"), a3 = structure(list(a1 = c("011", 
"012", "053"), b1 = c(2, 3, 12)), .Names = c("a1", "b1"), row.names = c(NA, 
-3L), class = "data.frame")), .Names = c("a1", "a2", "a3"))

list2=structure(list(b1 = structure(list(d1 = c("001", "002", "003"
), c1 = c("A", "B", "C")), .Names = c("d1", "c1"), row.names = c(NA, 
-3L), class = "data.frame"), b2 = structure(list(d1 = c("005", 
"006", "009"), c1 = c("D", "E", "F")), .Names = c("d1", "c1"), row.names = c(NA, 
-3L), class = "data.frame"), b3 = structure(list(d1 = c("011", 
"012", "053"), c1 = c("G", "H", "I")), .Names = c("d1", "c1"), row.names = c(NA, 
-3L), class = "data.frame")), .Names = c("b1", "b2", "b3"))

我想将list1中的所有数据框与list2中各自的数据框进行匹配,并考虑a1中的元素变量list1与变量{之间的匹配{1}}中的d1中的元素与每个数据框中的ID类似,但我会将list2中分配的c1变量list2变量添加到list1中的数据框{1}}。我想得到一个这样的新列表:

list.final

$a1

a1 b1 c1
001 12  A
002 13  B
003 12  C 

$a2

a1 b1 c1
005 12  D
006 16  E
009 16  F

$a3
a1 b1 c1
011  2  G
012  3  H
053 12  I

我正在尝试构建一个函数来进行匹配但是非常复杂,因为我对单个列表只有一些知识,在这里我必须使用两个可以拥有20个以上数据帧的列表。如果我可以有一个函数,我会使用llply中的plyr函数来创建新列表但我找不到解决方案。感谢。

2 个答案:

答案 0 :(得分:2)

这是mapply解决方案:

list.final <- mapply(merge, list1, list2, 
                            by.x = "a1", by.y = "d1", SIMPLIFY = FALSE)
list.final 
# $a1
#    a1 b1 c1
# 1 001 12  A
# 2 002 13  B
# 3 003 12  C
# 
# $a2
#    a1 b1 c1
# 1 005 12  D
# 2 006 16  E
# 3 009 16  F
# 
# $a3
#    a1 b1 c1
# 1 011  2  G
# 2 012  3  H
# 3 053 12  I

答案 1 :(得分:1)

merge看起来是最简单的解决方案,可能是我将用于解决这个小问题的解决方案。无论如何,这是一个data.table的解决方案。

library(data.table)
join_function = function( df1, df2 ) {
  dt1 = data.table(l1,key="a1")
  dt2 = data.table(l2,key="d1")
  dt1[dt2,]
}
Map(join_function, list1, list2)

现在解释一下。我把问题分解为逐个比较每个列表中的元素。为了进行比较,我创建了函数join_function。这些行

dt1 = data.table(l1,key="a1")
dt2 = data.table(l2,key="d1")

创建data.table个对象,可以将其视为具有附加功能的data.frames。每个key中的data.table对于进行连接至关重要。当要加入dt1dt2时,会按其键进行比较。如果dt1中的行和dt2中的行具有相同的键,则会合并这两行的列。所有这些工作都是在简单的代码

中完成的
dt1[dt2,]

行。这样就解决了为两个data.frame进行连接的问题。剩下的唯一事情是在两个列表中的每对数据帧上进行连接。这可以使用Map函数完成。这实际上多次应用了一个函数(第一个参数中提供的函数给Map。每个函数调用的参数都在Map调用的第二个和第三个参数中提供。这可能比你多了我想,但我刚想出如何使用data.table s并认为这样的解释可能会有所帮助。