Объединение данных, перезапись x на y, если y имеет значение - PullRequest
1 голос
/ 15 января 2020

У меня есть 2 кадра данных

DF x:

ID  A  B  C
1   x  y  z
2   x  y  z

DF y:

ID  A  B  C
1   NA d  f
2   e  NA NA

Я хочу объединить их таким образом, чтобы значение x перезаписывается значением y, но только в том случае, если для соответствующего столбца в x имеется значение в y.

Следовательно, результат вышеупомянутого должен быть:

ID  A  B  C
1   x  d  f
2   e  y  z

Ответы [ 2 ]

2 голосов
/ 15 января 2020

Один из вариантов: coalesce

library(dplyr)
left_join(dfx, dfy, by = 'ID') %>%
   transmute(ID, A = coalesce(A.y, A.x),
                 B = coalesce(B.y, B.x),
                 C = coalesce(C.y, C.x))
#   ID A B C
#1  1 x d f
#2  2 e y z

Или, если столбцов много, измените его в «длинный» формат, выполните coalesce, а затем преобразуйте в «широкий» формат

library(tidyr)
left_join(dfx, dfy, by = 'ID') %>%
   pivot_longer(cols = -ID, names_to = c("group", ".value"), names_sep = "\\.") %>% 
   mutate(x = coalesce(y, x)) %>%
   select(-y) %>% 
   pivot_wider(names_from = group, values_from = x)

Или другой вариант - bind_rows два набора данных, а затем сделать group_by summarise (при условии, что по одной строке 'ID')

bind_rows(dfy, dfx) %>% 
    group_by(ID) %>% 
    summarise_at(vars(-group_cols()), ~ first(.[!is.na(.)]))

Или используя соединение on data.table

library(data.table)
nm1 <- names(dfx)[-1]
nm2 <- paste0("i.", nm1)
setDT(dfy)[dfx, (nm1) := Map(coalesce, mget(nm1), mget(nm2)), on = .(ID)]

dfy

data

dfx <- structure(list(ID = 1:2, A = c("x", "x"), B = c("y", "y"), C = c("z", 
"z")), class = "data.frame", row.names = c(NA, -2L))

dfy <- structure(list(ID = 1:2, A = c(NA, "e"), B = c("d", NA), C = c("f", 
NA)), class = "data.frame", row.names = c(NA, -2L))
0 голосов
/ 15 января 2020

Используя базу R, мы можем получить индекс значений не-NA в dfy и заменить на него соответствующие значения dfx.

#Rearrange dfy if you have columns in different order than dfx
#dfy <- dfy[names(dfx)] 
inds <- which(!is.na(dfy[-1]), arr.ind = TRUE)
dfx[-1][inds] <- dfy[-1][inds]
dfx

#  ID A B C
#1  1 x d f
#2  2 e y z
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...