Мутировать с вложенным ifesle - PullRequest
2 голосов
/ 09 мая 2020

Я получаю неправильный результат, что я делаю не так?

df <- data.frame(x=c(1,1,NA),y=c(1,NA,NA),z=c(NA,NA,NA))
df <-mutate(df,result=ifelse(is.na(x),NA,ifelse(any(!is.na(y),!is.na(z)),1,0)))

Я получаю это (data [2,4] == 0)

   x  y  z result
1  1  1 NA      1
2  1 NA NA      1
3 NA NA NA     NA

Вместо это:

df_wanted <- data.frame(x=c(1,1,NA),y=c(1,NA,NA),z=c(NA,NA,NA), result=c(1,0,NA))

   x  y  z result
1  1  1 NA      1
2  1 NA NA      0
3 NA NA NA     NA

Ответы [ 2 ]

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

Мы можем использовать | вместо any, потому что any возвращает одно ИСТИНА / ЛОЖЬ в качестве вывода

with(df, any(!is.na(y), !is.na(z)))
#[1] TRUE

, и это повторно используется для всего столбца, и потому что первый ifelse с 'x' уже возвращается 'NA' для третьей строки, все остальные возвращаются 1

вместо этого нам нужно сделать это для каждой строки, и это может быть выполнено с помощью |

library(dplyr)
df %>%
   mutate(result = ifelse(is.na(x), NA, ifelse(!is.na(y)|!is.na(z), 1, 0)))
#   x  y  z result
#1  1  1 NA      1
#2  1 NA NA      0
#3 NA NA NA     NA

Или другой вариант: case_when

df %>%
  mutate(result = case_when(is.na(x) ~ NA_integer_, 
                        !is.na(y)| !is.na(z) ~ 1L, 
                        TRUE ~ 0L))
#   x  y  z result
#1  1  1 NA      1
#2  1 NA NA      0
#3 NA NA NA     NA

Или с coalesce

df %>%
   mutate(result = x * +coalesce(!is.na(y)|!is.na(z)))
#   x  y  z result
#1  1  1 NA      1
#2  1 NA NA      0
#3 NA NA NA     NA
0 голосов
/ 09 мая 2020

Вы можете использовать case_when и явно указать каждое условие.

library(dplyr)

df %>%
  mutate(result = case_when(is.na(x) ~ NA_integer_, 
                            !(is.na(y) & is.na(z)) ~ 1L, 
                            TRUE ~ 0L))


#   x  y  z result
#1  1  1 NA      1
#2  1 NA NA      0
#3 NA NA NA     NA
...