【问题标题】:Setting multiple if statements correctly正确设置多个 if 语句
【发布时间】:2018-04-30 18:32:44
【问题描述】:

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

所以预期的输出

    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

【问题讨论】:

  • 在 if 语句之后,您将返回 NA。您需要明确返回,例如return("good")

标签: r if-statement dplyr


【解决方案1】:

R 函数返回在其调用期间评估的最后一个值,即使没有显式调用 return(有关更多详细信息,请参阅 this answer);因此,NA 是在您的 if_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_)
}

【讨论】:

  • 看起来max(x)/2 == y[which(y == 15)]/3 始终为 TRUE,因此对于不满足第一个条件的任何行,结果将为 "y==5"。也许OP实际上想要x==max(x)/2 &amp; y/3==5 ~ "y==5"之类的东西?
  • @cmaher 感谢您的明确回答。当我运行你的新 if_state 时,我将所有类值都设为 y==5 ??
  • 见我上面的评论。
  • max(x)/2 为数据框中的每一行返回 5。 y[which(y == 15)]/3 为数据框中的每一行返回 5。所以被评估的条件是5==5,它总是为真。
  • 在函数调用中包装@cmaher 的答案(我也更改了第二个条件):if_state = function(x,y) {case_when( x == min(x) &amp;&amp; y == max(y) ~ "good", x == max(x)/2 &amp; y/3 == 5 ~ "y==5", TRUE ~ NA_character_ )}
猜你喜欢
  • 2017-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-16
  • 1970-01-01
  • 2015-07-30
相关资源
最近更新 更多