我有两张大桌子。一个带有标识符(未排序),另一个带有标识符列表(包含第一个表中的所有标识符)以及一个变量的关联值。 我想在第一个表中添加一列,其中包含第二个表中的关联值。有没有一种聪明的方法可以继续使用R的实现功能?
即
table 1
id
8979786
62782
6268768
6776566
table 2
id var
1 5
2 2
3 NA
…
9999999 6
,结果应为
table1
id var
8979786 5
62782 NA
6268768 7
4776566 4
提前致谢
答案 0 :(得分:4)
所以id
列在两个表中?您可以merge
将它们放在一起:merge(table1, table2, sort = FALSE)
。有很多选项需要探索合并,可以模拟不同类型的连接,类似于SQL中的内部,左侧,右侧和外部连接。我在这里添加了附加参数sort
以保留table1的原始顺序。
如果table1中有id但没有表2,并且您想要显示这些ID,请添加all.x = TRUE
作为参数。这相当于左连接。 all.y
是一个正确的联接,all = TRUE
相当于一个完整的外部联接。
可重复的例子:
> set.seed(1)
> table1 <- data.frame( id = sample(1:5, 5, FALSE))
> table1
id
1 2
2 5
3 4
4 3
5 1
> table2 <- data.frame( id = 1:5, var = rnorm(5))
> table2
id var
1 1 1.2724293
2 2 0.4146414
3 3 -1.5399500
4 4 -0.9285670
5 5 -0.2947204
> merge(table1, table2, sort = FALSE)
id var
1 2 0.4146414
2 5 -0.2947204
3 4 -0.9285670
4 3 -1.5399500
5 1 1.2724293
答案 1 :(得分:3)
如果数据很大且速度有问题,这是一种data.table方法。有关详细信息,请参阅?data.table
的帮助页面:
当i是data.table时,x(即外部data.table)必须有一个 键。 i(即内部data.table)使用key和x连接到x 返回x中匹配的行。执行等连接 在i的每一列之间到x的键中的每一列。这场比赛是一场比赛 在O(log n)时间内编译C中的二进制搜索。如果我的列数较少 比x的键,那么x的许多行可能与i的每一行匹配。如果我有 比x的键更多的列,我没有参与的列 加入包含在结果中。如果我也有钥匙,这是我的关键 用于匹配x的键列和二进制合并的列 这两个表的执行情况。
请注意,我稍微调整了Chase提供的示例数据,以使data.table
中的匹配更加明显:
require(data.table)
#Version 1.7.7
set.seed(1)
table1 <- data.table(id = sample(3:7, 5, FALSE), var1 = rnorm(5), key="id")
table2 <- data.table(id = 5:10, var2 = rnorm(6), key="id")
#Default: If id in table 1 is not in table 2, return NA
table2[table1]
# id var2 var1
# [1,] 3 NA -0.2947204
# [2,] 4 NA 1.2724293
# [3,] 5 -0.005767173 -0.9285670
# [4,] 6 2.404653389 -1.5399500
# [5,] 7 0.763593461 0.4146414
#If one wants to get rid of the NAs
table2[table1, nomatch=0]
# id var2 var1
# [1,] 5 -0.005767173 -0.9285670
# [2,] 6 2.404653389 -1.5399500
# [3,] 7 0.763593461 0.4146414
#Or the other way around: get all ids of table 2
table1[table2]
# id var1 var2
# [1,] 5 -0.9285670 -0.005767173
# [2,] 6 -1.5399500 2.404653389
# [3,] 7 0.4146414 0.763593461
# [4,] 8 NA -0.799009249
# [5,] 9 NA -1.147657009
# [6,] 10 NA -0.289461574
强制性速度测试:
set.seed(10)
df1 <- data.frame(id = sample(1:5e6, 5e6, FALSE))
df2 <- data.frame(id = sample(1:5e6, 5e6, FALSE), var = rnorm(5e6))
system.time(df_solution <- merge(df1, df2, sort = TRUE))
# user system elapsed
# 33.10 0.32 33.54
merge_dt <- function(df1, df2) {
dt1 <- setkey(as.data.table(df1), "id")
dt2 <- setkey(as.data.table(df2), "id")
return(dt1[dt2])
}
system.time(dt_solution <- merge_dt(df1, df2))
# user system elapsed
# 12.94 0.01 12.95
all.equal(df_solution, as.data.frame(dt_solution))
#[1] TRUE
我通常的免责声明:我还在学习这个软件包,所以你可以在package homepage找到更好的信息。
答案 2 :(得分:2)
我刚刚实现了一个解决这个问题的函数(合并两个data.frame对象,同时保持两个对象之一的顺序),你可以在这里看到它的代码和示例:
http://www.r-statistics.com/2012/01/merging-two-data-frame-objects-while-preserving-the-rows-order/