Как я могу игнорировать NA в нескольких столбцах в операторе if else в R?

#r #if-statement #dplyr

#r #if-statement #dplyr

Вопрос:

У меня есть фрейм данных, который выглядит следующим образом:

      a    b   c   d
10 yes      yes yes yes
11 yes      yes yes yes
12 yes      yes yes yes
13 yes      yes yes yes
14 no      <NA>  no  no
15 no      <NA>  no  no
16 no      <NA>  no  no
17 no      <NA>  no  no
18 no      <NA>  no  no
19 no      <NA>  no  no
20 no      <NA>  no  no
  

У меня есть оператор if else, который создает новый столбец со значениями 1,0 на основе того, являются ли ответы на все предыдущие столбцы да или нет. Однако мой код не учитывает NA.
Это код, который я использовал:

 y <- x %>%
  mutate(
    health_ever = ifelse(
      e == 'yes    ' |
        b == 'yes' |
        c == 'yes' |
        d == 'yes',
      1,
      0
    )
  )
  

Вот код для его воспроизведения:

 x<-structure(
  list(
    a = structure(
      c(6L, 6L, 6L, 6L, 7L, 7L,
        7L, 7L, 7L, 7L, 7L),
      .Label = c(
        "missing",
        "inapplicable",
        "proxy respondent       ",
        "refusal",
        "don't know",
        "yes    ",
        "no     "
      ),
      class = "factor"
    ),
    b = structure(
      c(6L, 6L, 6L, 6L, NA, NA, NA, NA, NA,
        NA, NA),
      .Label = c(
        "missing",
        "inapplicable",
        "proxy",
        "refusal",
        "don't know",
        "yes",
        "no"
      ),
      class = "factor"
    ),
    c = structure(
      c(6L,
        6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L),
      .Label = c(
        "missing",
        "inapplicable",
        "proxy",
        "refusal",
        "don't know",
        "yes",
        "no"
      ),
      class = "factor"
    ),
    d = structure(
      c(6L, 6L,
        6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L),
      .Label = c(
        "missing",
        "inapplicable",
        "proxy",
        "refusal",
        "don't know",
        "yes",
        "no"
      ),
      class = "factor"
    )
  ),
  row.names = 10:20,
  class = "data.frame"
)
  

Как я могу изменить свой код, чтобы игнорировать любой NAS, чтобы он по-прежнему выдавал 1,0 на основе других столбцов. Это мой желаемый результат:

      a            b        c        d            e
1   yes          yes      yes      yes           1
2   yes          yes      yes      yes           1
3   yes          yes      yes      yes           1
4   yes          yes      yes      yes           1
5   no          <NA>       no       no           0
6   no          <NA>       no       no           0
7   no          <NA>       no       no           0
8   no          <NA>       no       no           0
  

Ответ №1:

Использование rowSums в логической матрице может возвращать количество NA в каждой строке. Если он возвращает 0, это означает, что в этой строке нет NA . Это может быть преобразовано в логическое путем отрицания ( ! ), чтобы изменить 0 на TRUE, а все остальные значения на FALSE. Затем с помощью as.integer или принудительно преобразовать его в двоичный файл, т.Е. TRUE => 1 и FALSE => 0

 x$e <-  (!rowSums(is.na(x)))
  

Основываясь на коде OP, он проверяет значения ‘yes’, что также может быть выполнено с помощью rowSums

 x$e <-  (rowSums(x == 'yes', na.rm = TRUE) > 0)
  

т. Е. подсчитайте значения ‘yes’ в каждой строке, удалив NA с na.rm = TRUE , преобразуйте в логическое, проверяя, больше ли количество 0, и принудительно преобразуйте его в двоичный с помощью

Если мы хотим проверить, все ли столбцы должны быть «да»

 x$e <-  (rowSums(x == 'yes', na.rm = TRUE) == ncol(x))

 
  

-вывод

 x
#         a    b   c   d e
#10 yes      yes yes yes 1
#11 yes      yes yes yes 1
#12 yes      yes yes yes 1
#13 yes      yes yes yes 1
#14 no      <NA>  no  no 0
#15 no      <NA>  no  no 0
#16 no      <NA>  no  no 0
#17 no      <NA>  no  no 0
#18 no      <NA>  no  no 0
#19 no      <NA>  no  no 0
#20 no      <NA>  no  no 0
  

В коде OP есть начальный пробел в e == 'yes ' , а ‘e’ не является столбцом в исходном наборе данных. Возможно, ‘a’

Комментарии:

1. Как мне включить это в мой исходный код if else? Я не хочу полностью удалять свои строки NA

2. @H.B Это не удаление строк. Это создает новый столбец ‘e’

3. @H.B Я обновил сообщение. Пожалуйста, проверьте, работает ли это. Вложенный ifelse был бы менее эффективным

4. спасибо за ваш ответ! Если бы у меня были строки, которые содержали некоторые столбцы с Да, за которыми следовали строки с N / A, этот код также возвращает столбец e, заполненный 0. есть ли способ изменить это?

5. @H.B Вы хотите, чтобы условие было | или amp; ?