【问题标题】:How can I use case_when inside dplyr mutate() function?如何在 dplyr mutate() 函数中使用 case_when?
【发布时间】:2017-03-10 10:44:49
【问题描述】:

据我了解,case_when()ifelse() 的通用版本。

但是,我不明白如何在dplyr::mutate() 函数中使用这个函数。它曾经使用 github 的最新版本 dplyr 工作,但由于我回到了 CRAN 版本(0.5),它不再工作了。有人有线索吗?

这是我的可重现示例:


library(devtools)
library(tibble)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

tibble(
  group = c("A", "A", "A", "B", "B", "B"), 
  x = 1:6
  ) %>% 
  mutate(
    y = ifelse(group == "A", -x, x)
    )
#> # A tibble: 6 × 3
#>   group     x     y
#>   <chr> <int> <int>
#> 1     A     1    -1
#> 2     A     2    -2
#> 3     A     3    -3
#> 4     B     4     4
#> 5     B     5     5
#> 6     B     6     6

tibble(
  group = c("A", "A", "A", "B", "B", "B"), 
  x = 1:6
  ) %>% 
  mutate(
    y = case_when(
      group == "A" ~ -x, 
      TRUE ~ x
      )
  )
#> Error in mutate_impl(.data, dots): object 'group' not found

tibble(
  group = c("A", "A", "A", "B", "B", "B"), 
  x = 1:6
  ) %>%
  mutate_(
    .dots = list(
      "y" = lazyeval::interp( 
        ~ case_when(var1 == "A" ~ -var2, TRUE, var2), 
        var1 = as.name(group), 
        var2 = as.name(x)
        )
    )
  )
#> Error in as.name(group): object 'group' not found



devtools::session_info()
#> Session info -------------------------------------------------------------
#>  setting  value                       
#>  version  R version 3.3.2 (2016-10-31)
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language (EN)                        
#>  collate  C                           
#>  tz       <NA>                        
#>  date     2017-03-10
#> Packages -----------------------------------------------------------------
#>  package    * version     date       source                            
#>  assertthat   0.1         2013-12-06 CRAN (R 3.2.2)                    
#>  backports    1.0.5       2017-01-18 cran (@1.0.5)                     
#>  DBI          0.6         2017-03-09 cran (@0.6)                       
#>  devtools   * 1.12.0.9000 2017-03-07 Github (hadley/devtools@d8ab190)  
#>  digest       0.6.12      2017-01-27 cran (@0.6.12)                    
#>  dplyr      * 0.5.0       2016-06-24 CRAN (R 3.3.2)                    
#>  evaluate     0.10        2016-10-11 cran (@0.10)                      
#>  htmltools    0.3.5       2016-03-21 CRAN (R 3.2.3)                    
#>  knitr        1.15.1      2016-11-22 cran (@1.15.1)                    
#>  lazyeval     0.2.0.9000  2016-10-14 Github (hadley/lazyeval@c155c3d)  
#>  magrittr     1.5         2014-11-22 CRAN (R 3.2.3)                    
#>  memoise      1.0.0.9001  2017-02-13 Github (hadley/memoise@884d565)   
#>  pkgbuild     0.0.0.9000  2017-03-07 Github (r-pkgs/pkgbuild@65eace0)  
#>  pkgload      0.0.0.9000  2017-03-07 Github (r-pkgs/pkgload@fc907a1)   
#>  R6           2.2.0       2016-10-05 cran (@2.2.0)                     
#>  Rcpp         0.12.9      2017-01-14 cran (@0.12.9)                    
#>  rmarkdown    1.3.9004    2017-03-09 Github (rstudio/rmarkdown@01dc037)
#>  rprojroot    1.2         2017-01-16 cran (@1.2)                       
#>  stringi      1.1.2       2016-10-01 CRAN (R 3.3.1)                    
#>  stringr      1.2.0       2017-02-18 cran (@1.2.0)                     
#>  tibble     * 1.2         2016-08-26 CRAN (R 3.2.3)                    
#>  withr        1.0.2       2016-06-20 CRAN (R 3.2.3)                    
#>  yaml         2.1.14      2016-11-12 cran (@2.1.14)

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    dplyr 已更新,因此代码现在应该可以在不使用 .$ 或转换为 data.table 的情况下工作 - 请参阅 https://github.com/tidyverse/dplyr/issues/1965

    【讨论】:

      【解决方案2】:

      这行得通

      tibble(
        group = c("A", "A", "A", "B", "B", "B"), 
        x = 1:6
      ) %>% 
        mutate(y = case_when(.$group == "A" ~ -.$x, 
                             TRUE ~ .$x))
      

      【讨论】:

        【解决方案3】:

        将数据框转换为 data.table 可以让 case_when 按预期运行。

        library(dplyr)
        library(data.table)
        library(dtplyr)
        
        tibble(
          group = c("A", "A", "A", "B", "B", "B"), 
          x = 1:6) %>% 
        tbl_dt() %>%
        mutate(y = case_when(group == "A" ~ -x, 
                             TRUE ~ x))
        

        【讨论】:

          【解决方案4】:

          我发现了一个特殊的解决方法 - 似乎将数据帧通过管道进行变异而不是将其作为第一个参数包含在内,这样您就可以使用 case_when 并且它可以按预期工作。

          例如,这是有效的:

          df %>% mutate(new_var = case_when(old_var == 1 ~ TRUE,
                                            TRUE ~ FALSE)
          

          这不起作用:

          mutate(df, new_var = case_when(old_var == 1 ~ TRUE,
                                         TRUE ~ FALSE)
          

          (使用 R 3.3.1,dplyr 0.5.0)

          【讨论】:

            猜你喜欢
            • 2019-08-16
            • 2023-03-10
            • 1970-01-01
            • 2020-05-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多