Объединить два столбца, содержащие значения NA в дополняющих строках - PullRequest
0 голосов
/ 11 января 2020

Предположим, у меня есть этот фрейм данных

df <- data.frame(
    x=c(1, NA, NA, 4, 5, NA),
    y=c(NA, 2, 3, NA, NA, 6)

, который выглядит следующим образом

   x  y
1  1 NA
2 NA  2
3 NA  3
4  4 NA
5  5 NA
6 NA  6

Как я могу объединить два столбца в один? В основном значения NA находятся в дополнительных строках. Было бы также неплохо получить (в процессе) столбец flag, содержащий 0, если запись поступила из x и 1, если запись поступила из y.

Ответы [ 3 ]

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

Мы можем попробовать использовать функцию coalesce из пакета dplyr:

df$merged <- coalesce(df$x, df$y)
df$flag <- ifelse(is.na(df$y), 0, 1)
df

   x  y merged flag
1  1 NA      1    0
2 NA  2      2    1
3 NA  3      3    1
4  4 NA      4    0
5  5 NA      5    0
6 NA  6      6    1
1 голос
/ 11 января 2020

Мы также можем использовать base R методы с max.col на логической матрице для получения индекса столбца, cbind с индексом строки и извлечения значений, которые не являются NA

df$merged <- df[cbind(seq_len(nrow(df)), max.col(!is.na(df)))]
df$flag <- +(!is.na(df$y))
df
#   x  y merged flag
#1  1 NA      1    0
#2 NA  2      2    1
#3 NA  3      3    1
#4  4 NA      4    0
#5  5 NA      5    0
#6 NA  6      6    1

Или мы можем использовать fcoalesce из data.table, который записан в C и является многопоточным для чисел c и типов факторов.

library(data.table)
setDT(df)[, c('merged', 'flag' ) := .(fcoalesce(x, y), +(!is.na(y)))]
df
#    x  y merged flag
#1:  1 NA      1    0
#2: NA  2      2    1
#3: NA  3      3    1
#4:  4 NA      4    0
#5:  5 NA      5    0
#6: NA  6      6    1
0 голосов
/ 11 января 2020

Вы можете сделать это с помощью dplyr следующим образом:

library(dplyr)

# Creating dataframe
df <- 
  data.frame(
    x = c(1, NA, NA, 4, 5, NA),
    y = c(NA, 2, 3, NA, NA, 6))

df %>%
  # If x is null then replace it with y
  mutate(merged = coalesce(x, y),
         # If x is null then put 1 else put 0
         flag = if_else(is.na(x), 1, 0))

# x  y merged flag
# 1 NA      1    0
# NA  2      2    1
# NA  3      3    1
# 4 NA      4    0
# 5 NA      5    0
# NA  6      6    1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...