多列条件合并
Conditional merging on multiple columns
我有两个data.tables。我想将第二个 data.table 的信息与第一个合并:
DT1 <- fread(
"Val C D E F iso year
1 NA 1 NA NA NLD 2001
1 NA 2 NA NA NLD 2002
1 NA 3 NA NA GRC 2001
1 NA 3 NA NA GRC 2002",
header = TRUE)
DT2 <- fread(
"Val name O P Q R iso year
1 A NA 1 NA NA NLD 2001
1 A NA 2 NA NA NLD 2001
1 B NA 1 NA NA NLD 2001
1 B NA 2 NA NA NLD 2002
1 A NA 1 NA NA NLD 2002
1 B NA 2 NA NA NLD 2002
1 C NA 3 NA NA GRC 2001
1 C NA 3 NA NA GRC 2001
1 C NA 3 NA NA GRC 2001
1 A NA 3 NA NA GRC 2002
1 A NA 3 NA NA GRC 2002
1 B NA 3 NA NA GRC 2002",
header = TRUE)
我想把DT2
的name
下面的信息添加到DT1
如下。如果 iso
== NLD
名称 A
存在(无论多久),A 列将填充 A,如果不存在,则保持 NA:
DT1 <- fread(
"Val C D E F iso year A B C
1 NA 1 NA NA NLD 2001 A B NA
1 NA 2 NA NA NLD 2002 A B NA
1 NA 3 NA NA GRC 2001 NA NA C
1 NA 3 NA NA GRC 2002 A B NA",
header = TRUE)
但我不知道如何到达那里。我一直在尝试类似的东西:
DT[,A:="A"]
DT[,B:="B"]
DT[,C:="C"]
DT2$name[DT, on=c(iso="iso", year="year", name="A"), nomatch=0L]
或
merge(DT, DT2$name, on=c(iso="iso", year="year", A="name"), all.x = TRUE, allow.cartesian=FALSE)
但我认为必须以不同的方式解决它。谁能帮帮我?
Reshape DT2 合并前,如下所示。我们还需要一步将计数更改为 A、B、C:
merge(DT1, dcast(DT2[, -c(3:6)], iso + year + Val ~ name),
by = c("iso", "year", "Val"))
# Using 'year' as value column. Use 'value.var' to override
# Aggregate function missing, defaulting to 'length'
# iso year Val C.x D E F A B C.y
# 1: GRC 2001 1 NA 3 NA NA 0 0 3
# 2: GRC 2002 1 NA 3 NA NA 2 1 0
# 3: NLD 2001 1 NA 1 NA NA 2 1 0
# 4: NLD 2002 1 NA 2 NA NA 1 2 0
另一种使用密钥合并的方法:
library(data.table)
#adding a key column "temp" to both DT1 and DT2
DT1[,temp:=paste0(iso,year,"_",D)]
DT2[,temp:=paste0(iso,year,"_",P)]
#merge accoring to "temp"
DT3 <- merge(DT1,DT2)
#Casting variable name, a warning pops-out saying it uses lenght as aggregation
DT3 <- dcast(merge(DT1,DT2),Val+C+D+E+F+iso+year~name)
#output
DT3
Val C D E F iso year A B C
1: 1 NA 1 NA NA NLD 2001 1 1 0
2: 1 NA 2 NA NA NLD 2002 0 2 0
3: 1 NA 3 NA NA GRC 2001 0 0 3
4: 1 NA 3 NA NA GRC 2002 2 1 0
最后,为了使用 this 答案转换成所需的形式,我将其转换回数据框以更改最后三列 A、B、C 的值。请注意,C 是重复的,所以我'称它们为索引。
DT_final <- as.data.frame(DT3)
ind <- which(DT_final[,8:10]>0,arr.ind=TRUE) # is there a positive value?
DT_final[,8:10][ind]<- names(DT_final[,8:10])[ind[,"col"]]# if so change to the column name.
ind <- which(DT_final[,8:10]==0 ,arr.ind=TRUE)# is there zero value?
DT_final[,8:10][ind]<- NA # if so change to NA
DT_final
Val C D E F iso year A B C
1 1 NA 1 NA NA NLD 2001 A B <NA>
2 1 NA 2 NA NA NLD 2002 <NA> B <NA>
3 1 NA 3 NA NA GRC 2001 <NA> <NA> C
4 1 NA 3 NA NA GRC 2002 A B <NA>
我有两个data.tables。我想将第二个 data.table 的信息与第一个合并:
DT1 <- fread(
"Val C D E F iso year
1 NA 1 NA NA NLD 2001
1 NA 2 NA NA NLD 2002
1 NA 3 NA NA GRC 2001
1 NA 3 NA NA GRC 2002",
header = TRUE)
DT2 <- fread(
"Val name O P Q R iso year
1 A NA 1 NA NA NLD 2001
1 A NA 2 NA NA NLD 2001
1 B NA 1 NA NA NLD 2001
1 B NA 2 NA NA NLD 2002
1 A NA 1 NA NA NLD 2002
1 B NA 2 NA NA NLD 2002
1 C NA 3 NA NA GRC 2001
1 C NA 3 NA NA GRC 2001
1 C NA 3 NA NA GRC 2001
1 A NA 3 NA NA GRC 2002
1 A NA 3 NA NA GRC 2002
1 B NA 3 NA NA GRC 2002",
header = TRUE)
我想把DT2
的name
下面的信息添加到DT1
如下。如果 iso
== NLD
名称 A
存在(无论多久),A 列将填充 A,如果不存在,则保持 NA:
DT1 <- fread(
"Val C D E F iso year A B C
1 NA 1 NA NA NLD 2001 A B NA
1 NA 2 NA NA NLD 2002 A B NA
1 NA 3 NA NA GRC 2001 NA NA C
1 NA 3 NA NA GRC 2002 A B NA",
header = TRUE)
但我不知道如何到达那里。我一直在尝试类似的东西:
DT[,A:="A"]
DT[,B:="B"]
DT[,C:="C"]
DT2$name[DT, on=c(iso="iso", year="year", name="A"), nomatch=0L]
或
merge(DT, DT2$name, on=c(iso="iso", year="year", A="name"), all.x = TRUE, allow.cartesian=FALSE)
但我认为必须以不同的方式解决它。谁能帮帮我?
Reshape DT2 合并前,如下所示。我们还需要一步将计数更改为 A、B、C:
merge(DT1, dcast(DT2[, -c(3:6)], iso + year + Val ~ name),
by = c("iso", "year", "Val"))
# Using 'year' as value column. Use 'value.var' to override
# Aggregate function missing, defaulting to 'length'
# iso year Val C.x D E F A B C.y
# 1: GRC 2001 1 NA 3 NA NA 0 0 3
# 2: GRC 2002 1 NA 3 NA NA 2 1 0
# 3: NLD 2001 1 NA 1 NA NA 2 1 0
# 4: NLD 2002 1 NA 2 NA NA 1 2 0
另一种使用密钥合并的方法:
library(data.table)
#adding a key column "temp" to both DT1 and DT2
DT1[,temp:=paste0(iso,year,"_",D)]
DT2[,temp:=paste0(iso,year,"_",P)]
#merge accoring to "temp"
DT3 <- merge(DT1,DT2)
#Casting variable name, a warning pops-out saying it uses lenght as aggregation
DT3 <- dcast(merge(DT1,DT2),Val+C+D+E+F+iso+year~name)
#output
DT3
Val C D E F iso year A B C
1: 1 NA 1 NA NA NLD 2001 1 1 0
2: 1 NA 2 NA NA NLD 2002 0 2 0
3: 1 NA 3 NA NA GRC 2001 0 0 3
4: 1 NA 3 NA NA GRC 2002 2 1 0
最后,为了使用 this 答案转换成所需的形式,我将其转换回数据框以更改最后三列 A、B、C 的值。请注意,C 是重复的,所以我'称它们为索引。
DT_final <- as.data.frame(DT3)
ind <- which(DT_final[,8:10]>0,arr.ind=TRUE) # is there a positive value?
DT_final[,8:10][ind]<- names(DT_final[,8:10])[ind[,"col"]]# if so change to the column name.
ind <- which(DT_final[,8:10]==0 ,arr.ind=TRUE)# is there zero value?
DT_final[,8:10][ind]<- NA # if so change to NA
DT_final
Val C D E F iso year A B C
1 1 NA 1 NA NA NLD 2001 A B <NA>
2 1 NA 2 NA NA NLD 2002 <NA> B <NA>
3 1 NA 3 NA NA GRC 2001 <NA> <NA> C
4 1 NA 3 NA NA GRC 2002 A B <NA>