我有以下数据框a,b,c
Year<-rep(c("2002","2003"),1)
Crop<-c("TTT","RRR")
a<-data.frame(Year,Crop)
Year<-rep(c("2002","2003"),2)
ProductB<-c("A","A","B","B")
b<-data.frame(Year,ProductB)
Year<-rep(c("2002","2003"),3)
Location<-c("XX","XX","YY","YY","ZZ","ZZ")
c<-data.frame(Year,Location)
并希望将他们聚集在一起。当我使用merge
函数时,我得到的笛卡尔积不是我想要的。
d<-merge(a,b,by="Year")
e<-merge(d,c,by="Year")
我希望数据框看起来像
Year Crop ProductB Location
2002 TTT A XX
2002 NA B YY
2002 NA NA ZZ
2003 RRR A XX
2003 NA B YY
2003 NA NA ZZ
这可能吗?谢谢你的帮助
答案 0 :(得分:5)
这是使用data.table
的单向方式。
require(data.table) ## 1.9.2
# (1)
setDT(a)[, GRP := 1:.N, by=Year]
setDT(b)[, GRP := 1:.N, by=Year]
setDT(c)[, GRP := 1:.N, by=Year]
# (2)
merge(a, merge(b, c, by=c("Year", "GRP"),
all=TRUE), by=c("Year", "GRP"), all=TRUE)
# Year GRP Crop ProductB Location
# 1: 2002 1 TTT A XX
# 2: 2002 2 NA B YY
# 3: 2002 3 NA NA ZZ
# 4: 2003 1 RRR A XX
# 5: 2003 2 NA B YY
# 6: 2003 3 NA NA ZZ
- (1) -
的独特组合setDT
将data.frame
转换为data.table
,然后按GRP
分组创建新列Year
。有了这个,我们就拥有了Year, Grp
。- (2) - 我们合并了两列
Year, GRP
。
.N
是一个内置变量,用于保存该组的行数。
答案 1 :(得分:2)
Arun的回答将输出您想要的玩具示例。我只想添加两条评论。
首先。你没有得到笛卡尔积。这可以通过设置by = NULL
,比较以下行的输出来完成:
merge(a, b, by = "Year")
merge(a, b, by = NULL)
二。我看到你想要的输出是如何构造的。但我没有看到它背后的逻辑。我(或算法)如何知道,例如TTT
要与A
和XX
匹配,而不是NA
和ZZ
?为什么B
仅匹配YY
而不是ZZ
,比如说?
编辑:顺便说一句,Arun的策略也适用于merge
函数而没有data.table
包。
a$Grp <- seq_len(nrow(a))
b$Grp <- seq_len(nrow(b))
c$Grp <- seq_len(nrow(c))
d <- merge(a, b, by = c("Year", "Grp"), all = TRUE)
e <- merge(d, c, by = c("Year", "Grp"), all = TRUE)
e[,-2]