Установка нескольких операторов if правильно - PullRequest
0 голосов
/ 30 апреля 2018

Мне трудно установить правильное вложенное значение if statement в пользовательской функции.

Мои данные для примера такие

test <- data.frame(x=rev(0:10),y=10:20)

if_state <- function(x,y) {
  if (x==min(x) && y==max(y)) {
    "good"
  } else if (max(x)/2==y[which(y==15)]/3) {  # to find when x=5 and y=5 condition if it is true set class to "y==5"
    "y==5"
  }
    NA
}

   > test
    x  y
1  10 10
2   9 11
3   8 12
4   7 13
5   6 14
6   5 15
7   4 16
8   3 17
9   2 18
10  1 19
11  0 20

library(dplyr)
test %>%
  mutate(class = if_state(x,y))

    x  y class
1  10 10    NA
2   9 11    NA
3   8 12    NA
4   7 13    NA
5   6 14    NA
6   5 15    NA
7   4 16    NA
8   3 17    NA
9   2 18    NA
10  1 19    NA
11  0 20    NA

Я не знаю, почему оператор if не работает правильно? Вопрос в том, что является базовой функцией R, которая работает так же, как dplyr case_when? пожалуйста, смотрите комментарии ниже.

Итак, ожидаемый результат

    x  y class
1  10 10    NA
2   9 11    NA
3   8 12    NA
4   7 13    NA
5   6 14    NA
6   5 15    y==5
7   4 16    NA
8   3 17    NA
9   2 18    NA
10  1 19    NA
11  0 20    good

1 Ответ

0 голосов
/ 30 апреля 2018

Функции R возвращают последнее оцененное значение, оцененное во время их вызова, даже без явного вызова return (см. этот ответ для более подробной информации); поэтому, где NA является последним значением, оцененным в вашей функции if_state (так как оно находится вне потока управления if-else if и поэтому всегда будет оцениваться), оно всегда вернет NA, даже когда if и else if условия верны. Чтобы ваша функция работала так, как вы ожидаете, вам нужно переместить NA в оператор else:

if_state <- function(x,y) {
  if (x == min(x) && y == max(y)) {
    "good"
  } else if (max(x)/2 == y[which(y == 15)]/3) {
    "y==5"
  } else {
    NA 
  }
}

Обратите внимание, что при использовании dplyr тестирование нескольких условий для определения возвращаемого значения часто выполняется более кратко с помощью case_when:

test %>% mutate(class = case_when(
  x == min(x) && y == max(y) ~ "good",
  max(x)/2 == y[which(y == 15)]/3 ~ "y == 5",
  TRUE ~ NA_character_
))

Редактировать: на основании разъяснений ОП и помощи eipi10, вот последняя функция:

if_state = function(x, y) {
  case_when(x == min(x) && y == max(y) ~ "good", 
            x == max(x)/2 & y/3 == 5 ~ "y==5", 
            TRUE ~ NA_character_)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...