【问题标题】:ifelse statement in R is giving incorrect valuesR 中的 ifelse 语句给出的值不正确
【发布时间】:2021-05-04 11:10:54
【问题描述】:

我正在尝试使用 ifelse 语句根据计算的平均值提供“消息”。

这是我的代码。我没有收到错误消息,但睡眠水平不正确。

summary_sleep<-sleep_day %>%
group_by(Id)%>%
summarise(max_slept = max(TotalMinutesAsleep), 
mean_sleep=mean(TotalMinutesAsleep), 
 sum_sleep=sum(TotalMinutesAsleep),
number_sleep_entries=length(TotalMinutesAsleep))


summary_sleep$level_of_sleep = 
ifelse(summary_sleep$mean_sleep >= 460, "Too much sleep (OVER 460)",
ifelse(summary_sleep$mean_sleep >= 360 && summary_sleep$mean_sleep 
<=459, "Good sleep (360-460)",
ifelse(summary_sleep$mean_sleep >= 200 && summary_sleep$mean_sleep 
<=360, "Bad sleep (200-360)",
ifelse(summary_sleep$mean_sleep >0 && summary_sleep$mean_sleep <200, 
 "Bad sleep (0-200)"))))
ID mean_sleep level_of_sleep
1 294.0000 Good sleep (360-460)
2 61.000 Good sleep (360-460)
3 506.1786 Too much sleep (OVER 460)

【问题讨论】:

    标签: r if-statement stat


    【解决方案1】:

    对于复杂的情况,可能需要case_when(或ifelse)。在您的情况下,条件只是单个数字列的范围,您可以使用 cut 函数:

    summary_sleep$level_of_sleep = cut(summary_sleep$mean_sleep, 
                                       breaks = c(0, 200, 360, 460, Inf),
                                       labels = c("Bad sleep (0-200)", 
                                                  "Bad sleep (200-360)", 
                                                  "Good sleep (360-460)", 
                                                  "Too much sleep (OVER 460)"),
                                       include.lowest=TRUE)
    

    默认情况下,休息区将在右侧关闭并在左侧打开。要扭转这种情况,请使用参数right=FALSE

    关于您的 ifelse 声明:我认为由于使用 &amp;&amp; 而不是 &amp;,您得到的值不正确。您希望对 mean_sleep 的每个单独值进行单独的逻辑测试,但 &amp;&amp; 仅对向量的第一个值运行逻辑测试并返回单个 TRUEFALSE 结果。

    看看下面的例子。在Example 1 中,&amp; 版本为x 的每个值提供了单独的逻辑测试,但&amp;&amp; 仅使用x 的第一个值为我们提供了单个逻辑测试。由于x[1]=1,结果为FALSE。在Example 2 中,我重新排列了x,使值5 排在第一位。 5 满足条件,所以&amp;&amp; 现在返回TRUE

    # Example 1
    x = 1:10
    
    x >= 4 & x <= 6
    #>  [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE
    
    x >= 4 && x <= 6
    #> [1] FALSE
    
    # Example 2
    x = c(5, 1:4, 6:10)
    
    x >= 4 & x <= 6
    #>  [1]  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
    
    x >= 4 && x <= 6
    #> [1] TRUE
    

    以及在数据框中使用时的示例。请注意,在第二种情况下,我们首先对数据框进行排序:

    library(tidyverse)
    
    mtcars %>% 
      select(mpg) %>% 
      slice(1:10) %>% 
      mutate(
        `&&` = mpg >= 19 && mpg <= 21,
        `&` = mpg >= 19 & mpg <= 21,
        `mpg&&` = ifelse(mpg >= 19 && mpg <= 21, "Mid MPG", "Other"),
        `mpg&` = ifelse(mpg >= 19 & mpg <= 21, "Mid MPG", "Other")
      )
    #>                    mpg   &&     &   mpg&&    mpg&
    #> Mazda RX4         21.0 TRUE  TRUE Mid MPG Mid MPG
    #> Mazda RX4 Wag     21.0 TRUE  TRUE Mid MPG Mid MPG
    #> Datsun 710        22.8 TRUE FALSE Mid MPG   Other
    #> Hornet 4 Drive    21.4 TRUE FALSE Mid MPG   Other
    #> Hornet Sportabout 18.7 TRUE FALSE Mid MPG   Other
    #> Valiant           18.1 TRUE FALSE Mid MPG   Other
    #> Duster 360        14.3 TRUE FALSE Mid MPG   Other
    #> Merc 240D         24.4 TRUE FALSE Mid MPG   Other
    #> Merc 230          22.8 TRUE FALSE Mid MPG   Other
    #> Merc 280          19.2 TRUE  TRUE Mid MPG Mid MPG
    
    mtcars %>% 
      select(mpg) %>% 
      slice(1:10) %>% 
      arrange(mpg) %>%
      mutate(
        `&&` = mpg >= 19 && mpg <= 21,
        `&` = mpg >= 19 & mpg <= 21,
        `mpg&&` = ifelse(mpg >= 19 && mpg <= 21, "Mid MPG", "Other"),
        `mpg&` = ifelse(mpg >= 19 & mpg <= 21, "Mid MPG", "Other")
      )
    #>                    mpg    &&     & mpg&&    mpg&
    #> Duster 360        14.3 FALSE FALSE Other   Other
    #> Valiant           18.1 FALSE FALSE Other   Other
    #> Hornet Sportabout 18.7 FALSE FALSE Other   Other
    #> Merc 280          19.2 FALSE  TRUE Other Mid MPG
    #> Mazda RX4         21.0 FALSE  TRUE Other Mid MPG
    #> Mazda RX4 Wag     21.0 FALSE  TRUE Other Mid MPG
    #> Hornet 4 Drive    21.4 FALSE FALSE Other   Other
    #> Datsun 710        22.8 FALSE FALSE Other   Other
    #> Merc 230          22.8 FALSE FALSE Other   Other
    #> Merc 240D         24.4 FALSE FALSE Other   Other
    

    请参阅this SO answer 了解更多详细信息,了解为何在对值向量进行操作时应使用&amp;,而不是&amp;&amp;,其中您希望对每个值进行单独的逻辑测试。 (另外,请注意,在您的示例中,看起来第三个条件应该是 &lt; 360,而不是 &lt;= 360。)

    【讨论】:

    • 这很有趣。我是 R 新手,所以我什至不知道 cut 函数的存在。谢谢!!!
    【解决方案2】:

    您可能正在寻找case_when

    library(dplyr)
    summary_sleep %>% mutate(
     level_of_sleep = case_when(
        mean_sleep >= 460 ~ "Too much sleep (OVER 460)",
        mean_sleep >= 360 & mean_sleep <=459 ~ "Good sleep (360-460)",
        mean_sleep >= 200 & mean_sleep <360 ~ "Bad sleep (200-360)",
        mean_sleep > 0 & mean_sleep <200 ~ "Bad sleep (0-200)"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2014-07-12
      • 2018-11-11
      • 1970-01-01
      相关资源
      最近更新 更多