Объединение двух фреймов данных в одной совпадающей переменной и сохранение только одного значения для других непересекающихся переменных - PullRequest
2 голосов
/ 10 ноября 2019

У меня есть два кадра данных, которые мне нужно объединить. Фреймы данных совместно используют одни и те же столбцы. Я объединяюсь на основе одной общей переменной worker_ID. Однако другие переменные часто не пересекаются: один фрейм данных будет иметь «NA», а другой будет иметь другое значение для данной переменной. Как я могу объединить таким образом, чтобы выходные данные сохраняли только значения, отличные от NA?

x = worker_ID Var_1 Var_2 Var_3
    1         33    NA    NA
    2         NA    46    NA

y = worker_ID Var_1 Var_2 Var_3
    1         NA    75    NA
    2         NA    NA    66

z <- merge(x,y,by="worker_ID", all = TRUE)

Этот метод не работает, потому что вместо желаемого результата, z, я получаю фрейм данных с двумя столбцами длякаждая переменная (одна для значения переменной в x и другая для y). Мой желаемый вывод - это z.

z = worker_ID Var_1 Var_2 Var_3
    1         33    75    NA
    2         NA    46    66

Как я могу сказать R, чтобы любые записи не-NA заменяли записи NA?

1 Ответ

1 голос
/ 10 ноября 2019

Как предложил Бен, вы можете использовать coalesce(). Основываясь на ваших данных образца, я сделал следующее. Для каждой пары столбцов в одной и той же позиции в x и y я использовал coalesce() и создал вектор. Я преобразовал результат sapply() во фрейм данных и добавил worker_ID в конце. Обратите внимание, что я использовал as.numeric() для Var_3. Я не уверен, как ваши данные, но Var_3 в x может быть логическим, а не числовым. Я убедился, что Var_3 в x и Var_3 в 'y` оба числовые.

library(tidyverse)

sapply(2:ncol(x), function(whatever){
  coalesce(as.numeric(pull(x, whatever)),
           as.numeric(pull(y, whatever))) -> foo
  return(foo)
}) %>% 
as_tibble %>% 
bind_cols(work_ID = pull(x, 1), .)

#  A tibble: 2 x 4
#  work_ID    V1    V2    V3
#    <int> <dbl> <dbl> <dbl>
#1       1    33    75    NA
#2       2    NA    46    66

ОБНОВЛЕНИЕ

Принимая совет Акруна, я думаю, что следующий код работает хорошо. map_dfc() проходит через каждую пару столбцов так же, как sapply(). Хорошо, что map_dfc() создает фрейм данных;нет необходимости использовать as_tibble().

map_dfc(2:ncol(x), ~ coalesce(as.numeric(pull(x, .x)),
                              as.numeric(pull(y, .x)))) %>% 
bind_cols(work_ID = pull(x, 1), .)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...