【问题标题】:Why does case_when() compute false condition?为什么 case_when() 计算错误条件?
【发布时间】:2021-06-03 19:05:56
【问题描述】:

我有一个带有组变量和整数变量的 data.frame,但缺少数据。

df<-data.frame(group=c(1,1,2,2,3,3),a=as.integer(c(1,2,NA,NA,1,NA)))

我想计算每个组内变量 a 的最大可用值:在我的示例中,我应该为第 1 组获得 2,为第 2 组获得 NA,为第 3 组获得 1。

df %>% group_by(group) %>% mutate(max.a=case_when(sum(!is.na(a))==0 ~ NA_integer_,
                                                  T ~ max(a,na.rm=T)))

上面的代码产生了一个错误,似乎是因为在第 2 组中,a 的所有值都丢失了,所以max(a,na.rm=T) 被设置为-Inf,这不是一个整数。

为什么在条件为假的情况下为第 2 组计算这种情况,正如以下验证所证实的那样?

df %>% group_by(group) %>% mutate(test=sum(!is.na(a))==0)

我找到了一种将a 转换为双倍的解决方法,但我仍然收到警告和不满,因为没有找到更好的解决方案。

【问题讨论】:

  • case_when 是矢量化的。您在由sum 产生的标量上使用它,因此无法正常工作。按照答案中的建议使用未矢量化的if

标签: r dplyr


【解决方案1】:

case_when 评估条件的所有 RHS,无论条件是否满足,因此您会收到错误。如果所有值都是NA,您可以使用hablar::max_,它返回NA

library(dplyr)

df %>% 
  group_by(group) %>% 
  mutate(max.a= hablar::max_(a)) %>%
  ungroup

#  group     a max.a
#  <dbl> <int> <int>
#1     1     1     2
#2     1     2     2
#3     2    NA    NA
#4     2    NA    NA
#5     3     1     1
#6     3    NA     1

【讨论】:

    【解决方案2】:

    我建议不要使用case_when,而是像这样使用if () 语句:

    library(dplyr)
    
    df <- data.frame(group = c(1, 1, 2, 2, 3, 3), a = as.integer(c(1, 2, NA, NA, 1, NA)))
    
    df %>%
      group_by(group) %>%
      mutate(max.a = if (all(is.na(a))) NA_real_ else max(a, na.rm = T))
    #> # A tibble: 6 x 3
    #> # Groups:   group [3]
    #>   group     a max.a
    #>   <dbl> <int> <dbl>
    #> 1     1     1     2
    #> 2     1     2     2
    #> 3     2    NA    NA
    #> 4     2    NA    NA
    #> 5     3     1     1
    #> 6     3    NA     1
    

    【讨论】:

      【解决方案3】:

      此代码发出警告,但它有效。

      library(dplyr)
      df %>% 
        group_by(group) %>% 
        dplyr::summarise(max.a = max(a, na.rm=TRUE))
      

      输出:

        group max.a
        <dbl> <dbl>
      1     1     2
      2     2  -Inf
      3     3     1
      

      【讨论】:

        猜你喜欢
        • 2022-11-24
        • 2011-08-19
        • 1970-01-01
        • 2021-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-24
        • 2019-12-05
        相关资源
        最近更新 更多