Заполните значения NA в одной таблице данных наблюдаемыми значениями из второй таблицы данных в R - PullRequest
2 голосов
/ 28 января 2020

Не могу поверить, что у меня так много проблем с поиском решения этой проблемы: у меня есть две таблицы данных с одинаковыми строками и столбцами, которые выглядят так:

Country <- c("FRA", "FRA", "DEU", "DEU", "CHE", "CHE")
Year <- c(2010, 2020, 2010, 2020, 2010, 2020)
acctm <- c(20, 30, 10, NA, 20, NA)
acctf <- c(20, NA, 15, NA, 40, NA)

dt1 <- data.table(Country, Year, acctm, acctf)

   Country Year acctm acctf
1      FRA 2010    20    20
2      FRA 2020    30    NA
3      DEU 2010    10    15
4      DEU 2020    NA    NA
5      CHE 2010    20    40
6      CHE 2020    NA    NA

Country <- c("FRA", "FRA", "DEU", "DEU", "CHE", "CHE")
Year <- c(2010, 2020, 2010, 2020, 2010, 2020)
acctm <- c(1, 1, 1, 60, 1, 70)
acctf <- c(1, 60, 1, 80, 1, 100)

dt2 <- data.table(Country, Year, acctm, acctf)

   Country Year acctm acctf
1      FRA 2010    1     1
2      FRA 2020    2    60
3      DEU 2010    1     1
4      DEU 2020    60   80
5      CHE 2010    1     2
6      CHE 2020    70  100

Мне нужно создать новая таблица данных, которая заменяет NA значения в dt1 значениями для соответствующей страны / года / совпадения переменной из dt2, давая таблицу, которая выглядит следующим образом:

   Country Year acctm acctf
1      FRA 2010    20    20
2      FRA 2020    30    60
3      DEU 2010    10    15
4      DEU 2020    60    80
5      CHE 2010    20    40
6      CHE 2020    70   100

1 Ответ

3 голосов
/ 28 января 2020

Мы можем сделать это с помощью соединения on столбцы 'Страна', 'Год'

library(data.table)
nm1 <- names(dt1)[3:4]
nm2 <- paste0("i.", nm1)
dt3 <- copy(dt1)
dt3[dt2, (nm1) := Map(function(x, y) 
   fifelse(is.na(x), y, x), mget(nm1), mget(nm2)), on = .(Country, Year)]
dt3
#   Country Year acctm acctf
#1:     FRA 2010    20    20
#2:     FRA 2020    30    60
#3:     DEU 2010    10    15
#4:     DEU 2020    60    80
#5:     CHE 2010    20    40
#6:     CHE 2020    70   100

Или сделать этот компакт, используйте fcoalesce из data.table (комментарии @IceCreamToucan )

dt3[dt2,  (nm1) := Map(fcoalesce, mget(nm1), mget(nm2)), on = .(Country, Year)]

Если наборы данных имеют одинаковые измерения и имеют одинаковые значения для «Страна», «Год», тогда другой вариант -

library(purrr)
library(dplyr)
list(dt1[, .(acctm, acctf)], dt2[, .(acctm, acctf)]) %>% 
      reduce(coalesce) %>%
      bind_cols(dt1[, .(Country, Year)], .)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...