Объединение нескольких столбцов с использованием нескольких условий - PullRequest
5 голосов
/ 28 мая 2020

Я пытаюсь объединить несколько столбцов, используя несколько условных операторов. В приведенном ниже примере я хочу объединиться с A, имеющим приоритет над B, за которым следует C, где A составляет> = 0,1 и <30, а где A - это NA, <0,1 или> 30, я должен был объединиться с B, имеющим приоритет над A за которым следует C.

Ниже приведен пример набора данных:

df <- data.frame(1:8)
df$A <- c(102, 0.04, 0.1, NA_real_, 0.01, 0.01, 0.2, NA_real_)
df$B <- c(20.2, 50.1, 10.1, 6.1, 7.1, NA_real_, 8.1, NA_real_)
df$C <- c(NA_real_, 4.1, NA_real_, NA_real_, NA_real_, 8.1, NA_real_, 10.1)


      A    B    C
1   102 20.2   NA
2  0.04 50.1  4.1
3   0.1 10.1   NA
4    NA  6.1   NA
5  0.01  7.1   NA
6  0.01   NA  8.1
7   0.2  8.1   NA
8    NA   NA 10.1

Ниже желаемый результат:

      A    B    C new_col
1   102 20.2   NA    20.2
2  0.04 50.1  4.1    50.1
3   0.1 10.1   NA     0.1
4    NA  6.1   NA     6.1
5  0.01  7.1   NA     7.1
6  0.01   NA  8.1     8.1
7   0.2  8.1   NA     0.2
8    NA   NA 10.1    10.1

Я попытался решить эту проблему, используя функции mutate и coalesce в коде ниже, но не получил желаемого результата (во многих случаях это работает нормально, если значение в столбце A является значением, где значение - NA, на выходе создаются Null).

df <- df %>% 
  mutate(new_col = if_else(A >= 0.1 & A <= 30, 
                           coalesce(A, B, C),
                           coalesce(B, A, C)))

      A    B    C new_col
1   102 20.2   NA    20.2
2  0.04 50.1  4.1    50.1
3   0.1 10.1   NA     0.1
4    NA  6.1   NA    NULL
5  0.01  7.1   NA     7.1
6  0.01   NA  8.1    0.01
7   0.2  8.1   NA     0.2
8    NA   NA 10.1    NULL

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Мы можем использовать case_when

library(dplyr)
df %>%
    mutate(new_col = case_when(A >= 0.1 & A <= 30 & !is.na(A) ~ 
                   coalesce(A, B, C), TRUE ~ coalesce(B, A, C)))
1 голос
/ 28 мая 2020

Ваша попытка верна, но вам нужно обработать NA, поскольку NA in if_else возвращает NA.

library(dplyr)
df %>% 
  mutate(new_col = if_else(A >= 0.1 & A <= 30 & !is.na(A), 
                           coalesce(A, B, C),
                           coalesce(B, A, C)))


#       A    B    C new_col
#1 102.00 20.2   NA   20.20
#2   0.04 50.1  4.1   50.10
#3   0.10 10.1   NA    0.10
#4     NA  6.1   NA    6.10
#5   0.01  7.1   NA    7.10
#6   0.01   NA  8.1    0.01
#7   0.20  8.1   NA    0.20
#8     NA   NA 10.1   10.10

data

df <- data.frame(A = c(102, 0.04, 0.1, NA_real_, 0.01, 0.01, 0.2, NA_real_),
         B =  c(20.2, 50.1, 10.1, 6.1, 7.1, NA_real_, 8.1, NA_real_),
         C = c(NA_real_, 4.1, NA_real_, NA_real_, NA_real_, 8.1, NA_real_, 10.1))
...