我有两个数据集我想加入使用R-
数据集1
ID Name Date Price
1 A 2011 $100
2 B 2012 $200
3 C 2013 $300数据集2
ID Date Price
1 2012 $100
1 2013 $200
3 2014 $300通过ID在left-join()中使用dplyr,我最终会得到以下结果
ID Name Date.x Price.x Date.y Price.y
1 A 2011 $100 2012 $100
1 A 2011 $100 2013 $200
2 B 2012 $200
3 C 2013 $300 2014 $300然而,作为最终产品,我想要的是
ID Name Date Price
1 A 2011 $100
1 A 2012 $100
1 A 2013 $200
2 B 2012 $200
3 C 2013 $300
3 C 2014 $300也就是说,我不想合并到现有的行,而是在找到匹配时创建一个新行,并复制现有的不会更改的信息(ID和名称),并在必要时更改Date和Price列。对于如何在大型数据集上有效地执行此操作,有什么想法吗?
发布于 2016-08-03 19:02:50
您询问了有效的方法,所以我将介绍data.table:
library(data.table)
setDT(DF1)
setDT(DF2)
# structure your data so ID attributes are only in an ID table
idDT = DF1[, .(ID, Name)]
DF1[, Name := NULL]
# stack data
DT = rbind(DF1, DF2)
# grab ID attributes if you really need them
DT[idDT, on="ID", Name := i.Name]这给
ID Date Price Name
1: 1 2011 $100 A
2: 2 2012 $200 B
3: 3 2013 $300 C
4: 1 2012 $100 A
5: 1 2013 $200 A
6: 3 2014 $300 Crbind for data.tables是相当快的。不过,当只绑定两个表时,我并不认为效率会成为一个大问题。
关于剥离ID属性Name,它与dplyr的建议相匹配,后者将其称为making data tidy。
发布于 2016-08-03 19:58:48
这与弗兰克的回答略有不同。主要问题是您的第二个表没有Name列。使用data.table的update而连接方法可以非常有效地获得这一结果。
require(data.table)
dt2[dt1, Name := i.Name, on = "ID"] # by reference, no need to assign the result back现在有了一个Name列,我们可以简单地rbind结果。
ans = rbind(dt1, if (anyNA(dt2$Name)) na.omit(dt2, by="Name") else dt2)如果有必要,使用setorder()通过引用重新排序结果
setorder(ans, ID, Name) # by reference, no need to assign the result back
# ID Name Date Price
# 1: 1 A 2011 $100
# 2: 1 A 2012 $100
# 3: 1 A 2013 $200
# 4: 2 B 2012 $200
# 5: 3 C 2013 $300
# 6: 3 C 2014 $300:=操作符和set*函数在data.table中通过引用修改输入对象。
dt1 = fread('ID Name Date Price
1 A 2011 $100
2 B 2012 $200
3 C 2013 $300')
dt2 = fread('ID Date Price
1 2012 $100
1 2013 $200
3 2014 $300')发布于 2016-08-03 19:05:30
df1 <- data.frame(
ID=1:3,
Name=c("A","B","C"),
Date=c(2011,2012,2013),
Price=c(100,200,300)
)
df2 <- data.frame(
ID=c(1,1,3),
Date=c(2012,2013,2014),
Price=c(100,200,300)
)left_join不会给您提供所需的输出。您可以使用full_join。
merged <- full_join(df1, df2, by=c("Date","ID"))下面是使用melt从reshape2包获得所需输出的一种方法:
library(reshape2)
merged <- melt(merged, id.vars=c("ID","Name","Date"))然后:
> merged[na.omit(merged$Name), -4] #remove NAs and column from melt
ID Name Date value
1 1 A 2011 100
2 2 B 2012 200
3 3 C 2013 300
1.1 1 A 2011 100
2.1 2 B 2012 200
3.1 3 C 2013 300https://stackoverflow.com/questions/38751486
复制相似问题