通过合并另一行替换缺失值

时间:2018-07-25 12:39:25

标签: r data.table

我从不同来源读取数据到data.table中。两个源在同一时间步长提供不同的变量。

如何用其他来源(行)替换缺少的变量?

   Here is a minimal example: 
   (gg = data.table(SourceCode = c(1,1,2,2), time = c(1,2,1,2), LE = c(10,10,NA,NA), R = c(NA,NA,20,30)))
   SourceCode time LE  R
1:          1    1 10 NA
2:          1    2 10 NA
3:          2    1 NA 20
4:          2    2 NA 30

> # rename SourceCode
> gg[SourceCode == 1, SourceCode := 2 ]
> gg
   SourceCode time LE  R
1:          2    1 10 NA
2:          2    2 10 NA
3:          2    1 NA 20
4:          2    2 NA 30

所需的输出:

   SourceCode time LE  R
1:          2    1 10 20
2:          2    2 10 30

3 个答案:

答案 0 :(得分:1)

我最近有a similar question并发现了dplyr::coalesce()

简单的解决方案是:

library(dplyr)
coalesce(
  filter(gg, SourceCode == 2),
  filter(gg, SourceCode == 1)
)
  SourceCode time LE  R
1          2    1 10 20
2          2    2 10 30

但更笼统:

do.call(coalesce, split(gg, gg$SourceCode))
   SourceCode time LE  R
1:          1    1 10 20
2:          1    2 10 30

如果要基于第二个源(或最后一个源),可以执行以下操作:

do.call(coalesce, rev(split(gg, gg$SourceCode)))
   SourceCode time LE  R
1:          2    1 10 20
2:          2    2 10 30

答案 1 :(得分:0)

由于您似乎正在使用data.table,因此这里是一个data.table解决方案

unique(gg[, `:=`(LE = LE[!is.na(LE)], R = R[!is.na(R)]), by = time], by = "time")
#   SourceCode time LE  R
#1:          1    1 10 20
#2:          1    2 10 30

或者是第二个来源

unique(gg[, `:=`(LE = LE[!is.na(LE)], R = R[!is.na(R)]), by = time], by = "time", fromLast = T)
#   SourceCode time LE  R
#1:          2    1 10 20
#2:          2    2 10 30

由于SourceCode似乎不再相关(您总结了不同的SourceCode s),因此您也可以这样做

gg[, lapply(.SD, function(x) x[!is.na(x)]), by = time, .SDcols = 3:4]
#   time LE  R
#1:    1 10 20
#2:    2 10 30

答案 2 :(得分:0)

一个选项:

library(tidyverse)
dd %>% 
    gather(var, val, -SourceCode, -time) %>% 
    na.omit(val) %>% 
    spread(var, val)

#   SourceCode time LE  R
# 1          2    1 10 20
# 2          2    2 10 30

或其他基于分组的选项

dd %>% 
    group_by(SourceCode, time) %>% 
    summarise_at(vars(LE:R), .funs = funs(.[which(!is.na(.))]))

#   SourceCode time LE  R
# 1          2    1 10 20
# 2          2    2 10 30

请注意,我仅在group_by调用中添加了源代码以将其保留在摘要中。如果不需要该列,则可以省略。