R:按级别频率和绘图排序因子

use*_*017 4 r ggplot2 plyr dataframe r-factor

我有一个data.frame有几个因素,如:

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

summary(df$Var1)
 AB  BC  CD  DE  EF 
209 195 178 221 197
Run Code Online (Sandbox Code Playgroud)

我想在data.frame中绘制每个因子的级别频率,如下所示:

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

但是,级别的顺序是按字母顺序而不是按频率.使用次数库(plyr)我可以创建一个新data.frame,让我每一级的频率:

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

然后我可以使用它重新排序

df_count$Var1<-factor(df_count$Var1, levels=df_count$Var1[order(df_count$freq, decreasing=TRUE)])
Run Code Online (Sandbox Code Playgroud)

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

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"))
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*ker 6

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

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

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)))
Run Code Online (Sandbox Code Playgroud)

基本情节(错误的顺序):

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

在此输入图像描述

现在重新排序:

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

检查订单是否正确:

sort(table(df$Var1))
##  DE  AB  EF  CD  BC 
##  46 105 163 189 497 
Run Code Online (Sandbox Code Playgroud)

打印新的图表(使用以下方式粘贴新数据%+%并翻转图例的顺序guide_legend():您还可以使用function(x) -length(x)as FUN来更改级别的顺序).

print(g1 %+% df + 
    scale_fill_discrete(guide=guide_legend(reverse=TRUE)))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


aos*_*ith 5

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

library(forcats)

df$Var1 = fct_infreq(df$Var1)
Run Code Online (Sandbox Code Playgroud)

您可以使用命名向量来避免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"))
Run Code Online (Sandbox Code Playgroud)

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

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"))
Run Code Online (Sandbox Code Playgroud)


Flo*_*nGD 5

您还有一个使用库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"))
Run Code Online (Sandbox Code Playgroud)

饼形图

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

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

条形图