在两个数据表(dt1,dt2)上执行左外部联接的最简单方法是,填充值是0(或其他某个值)而不是NA(默认值)而不覆盖左数据表中的有效NA值?
常见的答案(例如在this thread中)是使用dplyr::left_join
或data.table::merge
或data.table
的dt2 [dt1]键列括号语法进行左外部联接,然后进行第二步,只需替换所有<联接数据表中NA
的cc>值。例如:
library(data.table);
dt1 <- data.table(x=c('a', 'b', 'c', 'd', 'e'), y=c(NA, 'w', NA, 'y', 'z'));
dt2 <- data.table(x=c('a', 'b', 'c'), new_col=c(1,2,3));
setkey(dt1, x);
setkey(dt2, x);
merged_tables <- dt2[dt1];
merged_tables[is.na(merged_tables)] <- 0;
该方法必须假定
0
中没有需要保留的有效NA值。但是,如您在上面的示例中看到的那样,结果是: x new_col y
1: a 1 0
2: b 2 w
3: c 3 0
4: d 0 y
5: e 0 z
但所需的结果是:
x new_col y
1: a 1 NA
2: b 2 w
3: c 3 NA
4: d 0 y
5: e 0 z
在这种微不足道的情况下,不是使用所有元素替换上述的
dt1
语法,而是可以替换data.table
中的NA值:library(dplyr);
merged_tables <- mutate(merged_tables, new_col = ifelse(is.na(new_col), 0, new_col));
但是,这种方法不适用于合并数十或数百个新列(有时带有动态创建的列名)的超大型数据集。即使事先知道所有列名,列出所有新列并对每个列进行mutate样式替换也很丑陋。
肯定有更好的办法?如果
new_col
,dplyr::left_join
或data.table::merge
括号中任何一个的语法都容易允许用户指定NA以外的data.table
值,则可以简单地解决该问题。就像是:merged_tables <- data.table::merge(dt1, dt2, by="x", all.x=TRUE, fill=0);
fill
的data.table
函数允许用户指定dcast
值,因此我认为必须有一种我没有想到的简便方法。有什么建议吗?
编辑:@jangorecki在评论中指出,当前在
fill
GitHug page上打开了一个功能请求,以准确执行我刚才提到的操作,更新了data.table
语法。应该在nomatch=0
的下一版本中。
最佳答案
您能否使用列索引仅引用新列,就像left_join
一样,它们都位于结果data.frame的右侧?它将在dplyr中:
dt1 <- data.frame(x = c('a', 'b', 'c', 'd', 'e'),
y = c(NA, 'w', NA, 'y', 'z'),
stringsAsFactors = FALSE)
dt2 <- data.frame(x = c('a', 'b', 'c'),
new_col = c(1,2,3),
stringsAsFactors = FALSE)
merged <- left_join(dt1, dt2)
index_new_col <- (ncol(dt1) + 1):ncol(merged)
merged[, index_new_col][is.na(merged[, index_new_col])] <- 0
> merged
x y new_col
1 a <NA> 1
2 b w 2
3 c <NA> 3
4 d y 0
5 e z 0
关于r - R左外连接以0填充代替NA,同时保留左表中的有效NA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35186694/