Логические операторы и строки: ошибка функции - PullRequest
1 голос
/ 22 октября 2019

Вот минимальный воспроизводимый пример, который генерирует ошибку:

 comb3 <- function(x) {
      if (x == "Unable to do") {
        x = 0
      } 
    } 

Вот моя оригинальная функция:

 comb <- function(x) {
      if (x == "Unable to do") {
        x = 0
      } else if (x == "Very difficult to do") {
        x = 1
      } else if (x == "Somewhat difficult to do") {
        x = 2
      } else if (x == "Not difficult") {
        x = 3
      } 
    }

Я пытаюсь использовать эту функцию в столбце, приведенном ниже,Я получаю эту ошибку:

Warning messages:
1: In if (x == "Unable to do") { :
  the condition has length > 1 and only the first element will be used
2: In if (x == "Very difficult to do") { :
  the condition has length > 1 and only the first element will be used

Here is a sample of what the data in one column looks like:
sample <- c("Unable to do", "Somewhat difficult to do", "Very difficult to do", "Unable to do", "Not difficult","Unable to do","Very difficult to do", "Not difficult", "Unable to do", "Not difficult")        

1 Ответ

0 голосов
/ 22 октября 2019

Предупреждающее сообщение довольно хорошо описывает проблему с вашим кодом. if - это функция, которая ожидает входной логический вектор длины один. Таким образом, чтобы использовать условные выражения над вектором, вместо этого вы должны использовать что-то вроде ifelse или, как сказал MrFlick, использовать case_when или mutate_at.

Эквивалентную версию вашей функции с использованием ifelse будетбыть примерно таким:

comb1 <- function(x) {
  ifelse(x == "Unable to do", 
    0,
    ifelse (x == "Very difficult to do",
      1,
      ifelse(x == "Somewhat difficult to do",
        2,
        ifelse(x == "Not difficult",
          3,
          ## If not match then NA
          NA
        )
      )
    )
  )
}

Обратите внимание, что это очень трудно читать, так как вызовы ifelse связаны друг с другом. Поэтому вы могли бы избежать этого, используя слегка измененную версию вашей функции при вызове sapply, чтобы выполнить то же самое

comb2 <- function(x) {
  sapply(x, function(y) {
    if (y == "Unable to do") {
      0
    } else if (y == "Very difficult to do") {
      1
    } else if (y == "Somewhat difficult to do") {
      2
    } else if (y == "Not difficult") {
       3
    }
  ## USE.NAMES = FALSE means that the output is not named, and has no other effect
  }, USE.NAMES = FALSE)
}

Вы также можете использовать факторы, которые внутренне кодируются как целые числа, начиная с 1и (ab) используйте это для преобразования строк в числа:

comb3 <- function(x) {
  fac <- factor(x, 
    levels = c(
      "Unable to do",
      "Very difficult to do",
      "Somewhat difficult to do",
      "Not difficult"
    )
  )
  as.numeric(fac) - 1
}

Вывод этих 3 версий идентичен и является отличным примером того, как может быть много способов достичь чего-либо в R. Иногда это может быть проклятием, а не подарком.

sample <- c("Unable to do", "Somewhat difficult to do", "Very difficult to do", "Unable to do", "Not difficult","Unable to do","Very difficult to do", "Not difficult", "Unable to do", "Not difficult")
comb1(sample)
# [1] 0 2 1 0 3 0 1 3 0 3
comb2(sample)
# [1] 0 2 1 0 3 0 1 3 0 3
comb3(sample)
# [1] 0 2 1 0 3 0 1 3 0 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...