合并两个数据帧时,如何将合并产生的NA
值设置为0,同时将先前存在的NA
值保留为NA
?
library(data.table)
df1 <- fread("
TYPE
A
B
C
")
df2 <- fread("
TYPE Num Dollar
A NA 215.77
B 11 NA
")
merge(df1, df2, all.x = T)
实际输出:
TYPE Num Dollar
1: A NA 215.77
2: B 11 NA
3: C NA NA
所需的输出:
TYPE Num Dollar
1: A NA 215.77
2: B 11 NA
3: C 0 0
编辑:这是一个更好的示例,显示了为什么在更一般的情况下不能依赖索引
df1 <- fread("
TYPE
A
B
C
", data.table = F)
df2 <- fread("
TYPE Num Dollar
A NA 215.77
C 11 NA
", data.table = F)
merge(df1, df2, all.x = T)
# TYPE Num Dollar
# 1 A NA 215.77
# 2 B NA NA
# 3 C 11 NA
inx <- which(is.na(df2), arr.ind = TRUE)
df3 <- merge(df1, df2, all.x = T)
df3[is.na(df3)] <- 0
df3[inx] <- NA
df3
# TYPE Num Dollar
# 1 A NA 215.77
# 2 B 0 NA
# 3 C 11 0.00
编辑:Rui Barradas和akrun的答案均有效。由于没有其他差异化因素,我接受Rui的回答,因为它适用于data.frame
和data.table
答案 0 :(得分:3)
也许有更简单的方法,但是下面的方法可以做到。
注意:
原始代码已被完全修改,以应对OP引用中的注释中所述的可能性。
这很好,但是仅在索引匹配时才有效。考虑一下 而不是C丢失,而df2中B丢失的情况。然后 来自df2的df3中的行具有索引1和3,而在df2中它们具有索引 有索引1和2
新代码解决了这两种情况,因此我将其放在函数中。
library(data.table)
fun <- function(DF1, DF2){
res <- merge(DF1, DF2, all.x = T, by = 'TYPE')
inx <- which(!(DF1$TYPE %in% DF2$TYPE))
res[inx, which(is.na(res[inx, ]))] <- 0
res
}
fun(df1, df2)
# TYPE Num Dollar
#1: A NA 215.77
#2: B 11 NA
#3: C 0 0.00
fun(df1, df3)
# TYPE Num Dollar
#1: A NA 215.77
#2: B 0 0.00
#3: C 11 NA
测试数据。
df1
和df2
是问题中的data.frame,df3
是OP注释中的df。
df1 <- fread("
TYPE
A
B
C
")
df2 <- fread("
TYPE Num Dollar
A NA 215.77
B 11 NA
")
df3 <- fread("
TYPE Num Dollar
A NA 215.77
C 11 NA
")
答案 1 :(得分:2)
除了@Rui Barradas解决方案之外,我们还可以在第二个数据集中创建一个flag变量并更改merge
的输出
out <- merge(df1, df2[, flag := TRUE], all.x = TRUE)
nm1 <- c("Num", "Dollar")
for(j in nm1) set(out, i = which(is.na(out$flag)), j=j, value = 0)
out[, flag := NULL][]
# TYPE Num Dollar
#1: A NA 215.77
#2: B 11 NA
#3: C 0 0.00
或使用加入
out <- copy(df1)
out[df2, c(nm1, 'flag') := c(mget(nm1), list(TRUE)), on = .(TYPE)]
然后如上所述将NA替换为0