【问题标题】:R: Sorting factor by level frequency and plottingR:按电平频率排序因子并绘图
【发布时间】:2017-07-18 17:37:09
【问题描述】:

我有一个 data.frame,其中包含以下几个因素:

df<-data.frame(Var1=as.factor(sample(c("AB", "BC", "CD", "DE", "EF"), 1000, replace=TRUE)))

summary(df$Var1)
 AB  BC  CD  DE  EF 
209 195 178 221 197

我想在 data.frame 中绘制每个因素的水平频率如下:

ggplot(df, aes(x=factor(1), fill=factor(Var1)))+
       geom_bar(width=1, colour="black")+
       coord_polar(theta="y")+
       theme_void()

但是,级别的顺序是按字母顺序排列的,而不是按频率排列的。使用 library(plyr) 中的 count 我可以创建一个新的 data.frame,它可以为我提供每个级别的频率:

df_count <-count(df, "Var1")
Var1 freq
1   AB  209
2   BC  195
3   CD  178
4   DE  221
5   EF  197

然后我可以使用

重新排序
df_count$Var1<-factor(df_count$Var1, levels=df_count$Var1[order(df_count$freq, decreasing=TRUE)])

绘制时给了我想要的,每个级别的排序频率。

1.) 这是最优雅的解决方案吗?它为我原始data.frame中的每个因子/列提供了一个额外的data.frame,我觉得必须有一个更简单的方法。

2.) 绘图时,如何重命名图例标签并确保为它们分配正确的因子级别?如果我使用

scale_fill_manual(labels=c("Name of AB", "Name of BC", "Name of CD", "Name of DE","Name of EF"))

标签与正确的级别无关。这里图例中的第一个条目将是“DE”,因为它是频率最高的级别,但标签会显示 scale_fill_manual 中定义的“AB 名称”。 我可以检查每次都手动标记,但必须有自动方式?

【问题讨论】:

    标签: r dataframe ggplot2 plyr r-factor


    【解决方案1】:

    您还有一个使用库forcats 和函数fct_infreq 的简单解决方案。

    library(forcats)
    ggplot(df, aes(x = factor(1), fill = fct_infreq(Var1)))+
      geom_bar(width = 1, colour = "black")+
      coord_polar(theta = "y")+
      theme_void() +
      guides(fill = guide_legend(title = "Var1"))
    

    请注意,饼图被认为是邪恶的(您可以用谷歌搜索),您可以使用简单的条形图传达相同的信息:

    ggplot(df, aes(x = fct_infreq(Var1), fill = fct_infreq(Var1))) +
      geom_bar(width = 1, colour = "black", show.legend = FALSE) +
      xlab("Var1")
    

    【讨论】:

      【解决方案2】:

      你想要reorder(),我想。通常reorder(x,y,FUN) 会根据将函数FUN 应用于第二个变量y 的结果来更改因子x 的级别顺序。在这种情况下,您可以使用FUN=length,而您使用y 并不重要。

      设置数据(我选择修改概率让结果更清晰):

      set.seed(101)
      df <- data.frame(Var1=as.factor(sample(c("AB", "BC", "CD", "DE", "EF"),
                                  prob=c(0.1,0.5,0.2,0.05,0.15),
                                         1000, replace=TRUE)))
      

      基本情节(顺序错误):

      library(ggplot2)
      print(g1 <- ggplot(df, aes(x=factor(1), fill=Var1))+
         geom_bar(width=1, colour="black")+
         coord_polar(theta="y")+
         theme_void())
      

      现在重新排序:

      df$Var1 <- reorder(df$Var1,df$Var1,FUN=length)
      levels(df$Var1)
      ## [1] "DE" "AB" "EF" "CD" "BC"
      

      检查顺序是否正确:

      sort(table(df$Var1))
      ##  DE  AB  EF  CD  BC 
      ##  46 105 163 189 497 
      

      打印新图(使用%+% 插入新数据并使用guide_legend() 翻转图例的顺序:您也可以使用function(x) -length(x) 作为FUN 来更改第一个级别的顺序地点)。

      print(g1 %+% df + 
          scale_fill_discrete(guide=guide_legend(reverse=TRUE)))
      

      【讨论】:

      • 这很完美,谢谢!结合 aosmith 的提示如何正确使用命名向量,它就像一个魅力:-)
      【解决方案3】:

      forcats 包中的函数可以帮助处理因子顺序。特别是fct_infreq 将根据每个级别的频率设置级别的顺序。

      library(forcats)
      
      df$Var1 = fct_infreq(df$Var1)
      

      您可以使用命名向量来避免scale_*_manual 函数中的顺序。

      scale_fill_manual(labels = c(AB = "Name of AB", 
                            BC = "Name of BC", 
                            CD = "Name of CD", 
                            DE = "Name of DE", 
                            EF = "Name of EF"))
      

      所以你的情节代码可能看起来像

      ggplot(df, aes(x = factor(1), fill = fct_infreq(Var1) ))+
          geom_bar(width = 1, colour = "black")+
          coord_polar(theta = "y")+
          theme_void() +
          scale_fill_discrete(labels = c(AB = "Name of AB", 
                                BC = "Name of BC", 
                                CD = "Name of CD", 
                                DE = "Name of DE", 
                                EF = "Name of EF"))
      

      【讨论】:

      • 感谢您的回答!我决定接受 Ben Bolker 的回答,因为它只使用基本函数,但是您对如何正确使用标签的向量的解释非常有帮助:-)
      猜你喜欢
      • 1970-01-01
      • 2013-04-08
      • 2017-08-08
      • 1970-01-01
      • 2017-11-07
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多