正确设置多个if语句

时间:2018-04-30 18:32:44

标签: r if-statement dplyr

我很难在用户定义的函数中设置正确的嵌套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语句不能正常工作? 问题是什么是与Rplyr case_when一样的基本R函数?请参阅下面的评论。

所以预期的产出

    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 :(得分:3)

R函数返回在调用期间评估的最后一个值,即使没有显式调用return(有关详细信息,请参阅this answer);所以,NAif_state函数中评估的最后一个值(因为它在if-else if控制流之外,因此将始终被评估),它将始终返回NA },即使ifelse 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_
))

编辑:根据OP的澄清和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_)
}