Заполнение нескольких столбцов отсутствующими данными из другого набора данных

У меня есть набор данных, который содержит некоторые пропущенные значения, которые можно заполнить путем слияния с другим набором данных. Мой пример:

Это обновленный набор данных, с которым я работаю.

DF1

Name Paper     Book       Mug        soap   computer tablet coffee coupons
1   2           3           4         5      6          7    8      9
2   21          22         23         23    23          7    23     9
3   56          57         58         59    60          7    62     9
4   80.33333    81.33333    82.33333  83    83.66667    7    85     9
5   107.3333    108.3333    109.3333 110    110.6667    7   112     9
6   134.3333    135.3333    136.3333 137    137.6667    7   139     9
7   161.3333    162.3333    163.3333 164    164.6667            
8   188.3333    189.3333    190.3333 191    191.6667    7   193     9
9   215.3333    216.3333    217.3333 218    218.6667    7   220     9
10  242.3333    243.3333    244.3333 245    245.6667    7   247     9
11  269.3333    270.3333    271.3333 272    272.6667    7   274     9
12  296.3333    297.3333    298.3333 299    299.6667            
13  323.3333    324.3333    325.3333 326    326.6667    7   328     9
14  350.3333    351.3333    352.3333 353    353.6667    7   355     9
15  377.3333    378.3333    379.3333 380    380.6667            
16  404.3333    405.3333    406.3333 407    407.6667    7   409     9
17  431.3333    432.3333    433.3333 434    434.6667    7   436     9
18  458.3333    459.3333    460.3333 461    461.6667    7   463     9
19  485.3333    486.3333    487.3333 488    488.6667            



DF2
Name    Paper   Book    Mug soap    computer    tablet  coffee  coupons
7   161.3333    162.3333    163.3333    164 164.6667    6   6   6
12  296.3333    297.3333    298.3333    299 299.6667    88  96  25
15  377.3333    378.3333    379.3333    380 380.6667    88  62  25
19  485.3333    486.3333    487.3333    488 488.6667    88  88  78

Я хочу получить:

Name Paper     Book       Mug        soap   computer tablet coffee coupons
1   2           3           4         5      6          7    8      9
2   21          22         23         23    23          7    23     9
3   56          57         58         59    60          7    62     9
4   80.33333    81.33333    82.33333  83    83.66667    7    85     9
5   107.3333    108.3333    109.3333 110    110.6667    7   112     9
6   134.3333    135.3333    136.3333 137    137.6667    7   139     9
7   161.3333    162.3333    163.3333 164    164.6667    6   6       6
8   188.3333    189.3333    190.3333 191    191.6667    7   193     9
9   215.3333    216.3333    217.3333 218    218.6667    7   220     9
10  242.3333    243.3333    244.3333 245    245.6667    7   247     9
11  269.3333    270.3333    271.3333 272    272.6667    7   274     9
12  296.3333    297.3333    298.3333 299    299.6667    88  96      25      
13  323.3333    324.3333    325.3333 326    326.6667    7   328     9
14  350.3333    351.3333    352.3333 353    353.6667    7   355     9
15  377.3333    378.3333    379.3333 380    380.6667    88   62     25      
16  404.3333    405.3333    406.3333 407    407.6667    7   409     9
17  431.3333    432.3333    433.3333 434    434.6667    7   436     9
18  458.3333    459.3333    460.3333 461    461.6667    7   463     9
19  485.3333    486.3333    487.3333 488    488.6667    88  88      78

Я пробовал следующий код:

DF1[,c(4:6)][is.na(DF1[,c(4:6)]<-DF2[,c(2:4)][match(DF1[,1],DF2[,1])] 
[which(is.na(DF1[,c(4:6)]))]

Одно из решений с использованием dplyr будет работать, если я пропущу столбцы, которые уже заполнены. Не уверен, что это моя версия dplyr, которую я обновил на прошлой неделе.

Любая помощь приветствуется! Спасибо!


person JeffB    schedule 30.10.2020    source источник


Ответы (1)


Мы можем выполнить left соединение, а затем coalesce столбцы.

library(dplyr)
DF1 %>%
     left_join(DF2, by = c('NameVar')) %>% 
      transmute(NameVar, Var1, Var2, 
                Var3 = coalesce(Var3.x, Var3.y), 
                Var4 = coalesce(Var4.x, Var4.y), 
                Var5 = coalesce(Var5.x, Var5.y))

-выход

#   NameVar Var1 Var2 Var3 Var4 Var5
#1    Sub1   30   45   40   34   65
#2    Sub2   25   30   30   45   45
#3    Sub3   74   34   25   30   49
#4    Sub4   30   45   40   34   65
#5    Sub5   25   30   69   56   72
#6    Sub6   74   34   74   34   60

Или используя data.table

library(data.table)
nm1 <- setdiff(intersect(names(DF1), names(DF2)), 'NameVar')
setDT(DF1)[DF2, (nm1) := Map(fcoalesce, mget(nm1),
     mget(paste0("i.", nm1))), on = .(NameVar)]

данные

DF1 <- structure(list(NameVar = c("Sub1", "Sub2", "Sub3", "Sub4", "Sub5", 
"Sub6"), Var1 = c(30L, 25L, 74L, 30L, 25L, 74L), Var2 = c(45L, 
30L, 34L, 45L, 30L, 34L), Var3 = c(40L, NA, NA, 40L, 69L, NA), 
    Var4 = c(34L, NA, NA, 34L, 56L, NA), Var5 = c(65L, NA, NA, 
    65L, 72L, NA)), class = "data.frame", row.names = c(NA, -6L
))

DF2 <- structure(list(NameVar = c("Sub2", "Sub3", "Sub6"), Var3 = c(30L, 
25L, 74L), Var4 = c(45L, 30L, 34L), Var5 = c(45L, 49L, 60L)),
class = "data.frame", row.names = c(NA, 
-3L))
person akrun    schedule 30.10.2020
comment
ах, ты опередил меня, Арун. - person Karthik S; 30.10.2020
comment
Я получаю следующий код ошибки: Ошибка: неожиданное '=' в: преобразование (Var1:Var3, Var4 = Ошибка: неожиданное ',' в Var5= объединение (df1$var5, df2$var5 и Error: Unexpected ') ' в Var6= объединение (df1$var6, df2$var6, Любые идеи, что я делаю неправильно? - person JeffB; 02.11.2020
comment
@JeffB Не могли бы вы проверить свой packageVersion('dplyr'). Я попробовал код еще раз, и он работает нормально - person akrun; 03.11.2020
comment
Я обновил свой пакет dplyr. Это работает, когда я удаляю Var 2 и Var3 из кода. Когда я включаю Var2 и Var3, я получаю сообщение об ошибке «Ошибка: проблема с входом mutate() ..2». x объект 'Var2' не найден i Вход ..2 равен Var2. Есть идеи, почему это происходит? - person JeffB; 03.11.2020
comment
@JeffB, это странная ошибка. Ошибка основана на тех же данных из моего сообщения - person akrun; 03.11.2020
comment
Нет, это не так. Но я сделал еще один фиктивный набор данных, и у меня все те же проблемы. - person JeffB; 05.11.2020
comment
@JeffB Можете ли вы обновить. с dput ваших примеров наборов данных, чтобы я мог их протестировать - person akrun; 06.11.2020
comment
@akrun, извините, я только что это увидел. Я обновил набор данных, к которому пробовал ваш код. Я получаю тот же код ошибки. Спасибо за помощь! - person JeffB; 10.11.2020
comment
@JeffB Это NA или "" в ваших данных. Если бы это было dput, было бы легче узнать структуру - person akrun; 10.11.2020