按组统计重新排序因子

Reorder factors by a group statistic

我知道这应该是直截了当的,但它总是让我头疼。
假设我有一个因子:

library(dplyr)
library(forcats)
fruits <- as.factor(c("apples", "oranges", "oranges", "pears", "pears", "pears"))
df <- as.data.frame(fruits)

我想根据频率(或其他一些统计数据)对因素重新排序,以便梨 > 橘子 > 苹果。我该怎么做 而不 显式调用 df %>% group_by(fruits) %>% summarise(freq = n()) %>% fct_reorder(fruits, freq, .desc = TRUE)?

我们可能需要在 mutate 中使用它。

library(dplyr)
library(forcats)
out <- df %>% 
   group_by(fruits) %>% 
   summarise(freq = n(), .groups = 'drop') %>% 
   mutate(fruits = fct_reorder(fruits, freq, .desc = TRUE))

-检查levels

的顺序
levels(out$fruits)
[1] "pears"   "oranges" "apples" 
levels(df$fruits)
[1] "apples"  "oranges" "pears"  

如果我们想在原始数据集上执行此操作,而不是 summarise,请使用 add_count 创建频率列,然后应用 fct_reorder

df <- df %>% 
    add_count(fruits) %>% 
    mutate(fruits = fct_reorder(fruits, n, .desc = TRUE)) %>% 
    select(-n)

注意:1.0.6 中的 group_by - dplyr 版本没有 .desc 参数。 .desc 位于 fct_reorder


base R中,我们可以用table

来做到这一点
out1 <- table(fruits)
factor(fruits, levels = names(out1[order(-out1)]))
[1] apples  oranges oranges pears   pears   pears  
Levels: pears oranges apples

我想我们也可以用 fct_infreq:

library(forcats)

df %>%
  {fct_infreq(.$fruits)}

[1] apples  oranges oranges pears   pears   pears  
Levels: apples oranges pears

或者这一个:

df %>% 
  mutate(fruits = fruits %>% 
           fct_infreq() %>% 
           fct_rev()) %>% 
  pull(fruits)

   fruits
1  apples
2 oranges
3 oranges
4   pears
5   pears
6   pears