R:转换为与 case_when 相同的级别顺序的因子

Den*_* YL 12 r data-analysis dplyr tidyverse forcats

在进行数据分析时,有时需要将值重新编码为因子以进行组分析。我想保持因子的顺序与case_when. 在这种情况下,顺序应该是"Excellent" "Good" "Fail"。我怎样才能做到这一点而不像在levels=c('Excellent', 'Good', 'Fail')

非常感谢。

library(dplyr, warn.conflicts = FALSE)             

set.seed(1234)                                     
score <- runif(100, min = 0, max = 100)     

Performance <- function(x) {                       
  case_when(                                         
    is.na(x) ~ NA_character_,                          
    x > 80   ~ 'Excellent',                            
    x > 50   ~ 'Good',                                 
    TRUE     ~ 'Fail'                                  
  ) %>% factor(levels=c('Excellent', 'Good', 'Fail'))
}                                                  

performance <- Performance(score)                  
levels(performance)                                
#> [1] "Excellent" "Good"      "Fail"
table(performance)                                 
#> performance
#> Excellent      Good      Fail 
#>        15        30        55
Run Code Online (Sandbox Code Playgroud)

编辑:我的解决方案

最后,我想出了一个解决方案。对于那些有兴趣的人,这是我的解决方案。我写了一个函数fct_case_when(假装是 中的函数forcats)。它只是case_when带因子输出的包装器。级别的顺序与参数顺序相同。

fct_case_when <- function(...) {
  args <- as.list(match.call())
  levels <- sapply(args[-1], function(f) f[[3]])  # extract RHS of formula
  levels <- levels[!is.na(levels)]
  factor(dplyr::case_when(...), levels=levels)
}
Run Code Online (Sandbox Code Playgroud)

现在,我可以使用fct_case_when代替case_when,结果将与之前的实现相同(但不那么乏味)。

Performance <- function(x) {                       
  fct_case_when(                                         
    is.na(x) ~ NA_character_,                          
    x > 80   ~ 'Excellent',                            
    x > 50   ~ 'Good',                                 
    TRUE     ~ 'Fail'                                  
  )
}      
performance <- Performance(score)                  
levels(performance)                       
#> [1] "Excellent" "Good"      "Fail"
table(performance)                
#> performance
#> Excellent      Good      Fail 
#>        15        30        55
Run Code Online (Sandbox Code Playgroud)

小智 12

我的解决方案

最后,我想出了一个解决方案。对于那些感兴趣的人,这是我的解决方案。我写了一个函数fct_case_when(假装是 中的函数forcats)。case_when它只是因子输出的包装。级别的顺序与参数顺序相同。


fct_case_when <- function(...) {
  args <- as.list(match.call())
  levels <- sapply(args[-1], function(f) f[[3]])  # extract RHS of formula
  levels <- levels[!is.na(levels)]
  factor(dplyr::case_when(...), levels=levels)
}
Run Code Online (Sandbox Code Playgroud)

现在,我可以使用fct_case_when代替case_when,结果将与之前的实现相同(但不那么繁琐)。


Performance <- function(x) {                       
  fct_case_when(                                         
    is.na(x) ~ NA_character_,                          
    x > 80   ~ 'Excellent',                            
    x > 50   ~ 'Good',                                 
    TRUE     ~ 'Fail'                                  
  )
}      
performance <- Performance(score)                  
levels(performance)                       
#> [1] "Excellent" "Good"      "Fail"
table(performance)                
#> performance
#> Excellent      Good      Fail 
#>        15        30        55
Run Code Online (Sandbox Code Playgroud)