我正在绘制类别变量,而不是显示每个类别值的计数。

我正在寻找一种方法来获取ggplot以显示该类别中值的百分比。当然,可以使用计算出的百分比创建另一个变量并绘制该变量,但我不得不重复数十次,我希望用一个命令来实现。

我正在尝试带有类似

qplot(mydataf) +
  stat_bin(aes(n = nrow(mydataf), y = ..count../n)) +
  scale_y_continuous(formatter = "percent")


的东西,但是由于出现错误,我必须使用不正确。

为了轻松地重现设置,这是一个简化的过程例如:

mydata <- c ("aa", "bb", NULL, "bb", "cc", "aa", "aa", "aa", "ee", NULL, "cc");
mydataf <- factor(mydata);
qplot (mydataf); #this shows the count, I'm looking to see % displayed.


在实际情况下,我可能会使用ggplot而不是qplot,但是正确的使用stat_bin的方法仍然困扰着我。

我也尝试了这四种方法:

ggplot(mydataf, aes(y = (..count..)/sum(..count..))) + 
  scale_y_continuous(formatter = 'percent');

ggplot(mydataf, aes(y = (..count..)/sum(..count..))) + 
  scale_y_continuous(formatter = 'percent') + geom_bar();

ggplot(mydataf, aes(x = levels(mydataf), y = (..count..)/sum(..count..))) + 
  scale_y_continuous(formatter = 'percent');

ggplot(mydataf, aes(x = levels(mydataf), y = (..count..)/sum(..count..))) + 
  scale_y_continuous(formatter = 'percent') + geom_bar();


,但全部4个都给出:


Error: ggplot2 doesn't know how to deal with data of class factor



ggplot (data=mydataf, aes(levels(mydataf))) +
  geom_bar()

的简单情况也会出现相同的错误,因此显然ggplot如何与单个向量相互作用。我挠头,搜索该错误只会得到一个结果。

评论

数据应该是数据帧,而不是裸露的因素。

添加到hadley的注释中,使用mydataf = data.frame(mydataf)将您的数据转换为数据帧,并将其重命名为names(mydataf)= foo即可完成操作

#1 楼

自从回答了这个问题以来,对ggplot语法进行了一些有意义的更改。总结以上评论中的讨论:

 require(ggplot2)
 require(scales)

 p <- ggplot(mydataf, aes(x = foo)) +  
        geom_bar(aes(y = (..count..)/sum(..count..))) + 
        ## version 3.0.0
        scale_y_continuous(labels=percent)


这里是使用mtcars的可复制示例:

 ggplot(mtcars, aes(x = factor(hp))) +  
        geom_bar(aes(y = (..count..)/sum(..count..))) + 
        scale_y_continuous(labels = percent) ## version 3.0.0




此问题当前在Google上的“ ggplot计数与直方图百分比”排名第一,因此希望这有助于提取当前包含在对已接受答案的评论中的所有信息。

备注:如果未将hp设置为因子,则ggplot返回:



评论


感谢您的回答。关于如何在课堂上做到这一点的任何想法吗?

– WAF
2015年2月25日在15:07

正如。@ WAF所建议的,此答案不适用于分面数据。请参阅stackoverflow.com/questions/22181132/中的@Erwan的评论。

–LeeZamparo
15年11月11日在20:49

您可能需要在%之前加上软件包的前缀,以使上述内容起作用(我做到了)。 ggplot(mtcars,aes(x = factor(hp)))+ geom_bar(aes(y =(..count ..)/ sum(.. count ..))))+ scale_y_continuous(labels = scales :: percent)

–哺乳动物
19年5月22日在16:22



要避开使用方面,请改用geom_bar(aes(y =(..count ..)/ tapply(.. count ..,.. PANEL ..,sum)[.. PANEL ..])))。每个方面的总和应为100%。

– JWilliman
19年8月14日在1:07

变量周围是否带有“ ..”的变量不是用stat()-命令代替吗? ggplot2.tidyverse.org/reference/stat.html

–马格努斯
19年11月14日在14:18

#2 楼

此修改后的代码应该起作用

p = ggplot(mydataf, aes(x = foo)) + 
    geom_bar(aes(y = (..count..)/sum(..count..))) + 
    scale_y_continuous(formatter = 'percent')


如果您的数据具有NA,并且您不希望它们包含在图中,则将na.omit(mydataf)作为参数传递给ggplot。

希望有帮助。

评论


请注意,在ggplot2 0.9.0版中,formatter参数将不再起作用。相反,您需要的是labels = percent_format())。

– joran
2012年3月3日,0:02

对于0.9.0,您需要在使用percent_format()之前加载比例尺库,否则它将无法正常工作。 0.9.0不再自动加载支持软件包。

–安德鲁(Andrew)
2012年3月16日在6:22

看到了吗? stat_bin。它显示了ggplot2将哪些其他列添加到了数据帧。所有其他列的格式均为..variable ...


2014年5月17日13:42

用简单的aes(y = ..density ..)替换aes(y =(..count ..)/ sum(.. count ..))是否有意义?从视觉上看,它给出了非常相似(但仍然不同)的图片

–亚历山大·科森科夫(Alexander Kosenkov)
2014年6月11日22:01在

在ggplot 0.9.3.1.0中,您首先要加载scales库,然后使用docs中提到的scale_y_continuous(labels = percent)

–adilapapaya
2014年10月7日22:56

#3 楼

对于ggplot2版本2.1.0,它是

+ scale_y_continuous(labels = scales::percent)


#4 楼

截至2017年3月,使用ggplot2 2.2.1,我认为最佳解决方案已在Hadley Wickham的R数据科学书中进行了解释:

ggplot(mydataf) + stat_count(mapping = aes(x=foo, y=..prop.., group=1))


stat_count计算两个变量:count为默认使用,但您可以选择使用显示比例的prop

评论


截至2017年6月,这是最佳答案,适用于按组填充和多方面填充。

– Skumin
17年6月29日在15:52

由于某些原因,这不允许我使用填充映射(不会引发任何错误,但不会添加填充颜色)。

– Max Candocia
18年4月7日在3:20

@MaxCandocia我必须删除group = 1才能获得填充映射。也许有帮助

– Tjebo
18年4月25日在18:27

但是,如果删除组参数,则它不会显示正确的百分比,因为对于每个唯一的x值,一切都属于其自己的组。

– Max Candocia
18-04-25在19:41

#5 楼

如果要在y轴上用百分比标出并在条形图上标出:

library(ggplot2)
library(scales)
ggplot(mtcars, aes(x = as.factor(am))) +
  geom_bar(aes(y = (..count..)/sum(..count..))) +
  geom_text(aes(y = ((..count..)/sum(..count..)), label = scales::percent((..count..)/sum(..count..))), stat = "count", vjust = -0.25) +
  scale_y_continuous(labels = percent) +
  labs(title = "Manual vs. Automatic Frequency", y = "Percent", x = "Automatic Transmission")




添加条形图标签时,您可能希望在末尾添加以下内容以省略y轴以生成更清晰的图表:

  theme(
        axis.text.y=element_blank(), axis.ticks=element_blank(),
        axis.title.y=element_blank()
  )




#6 楼

这是分面数据的解决方法。 (@Andrew接受的答案在这种情况下不起作用。)这个想法是使用dplyr计算百分比值,然后使用geom_col创建图。

library(ggplot2)
library(scales)
library(magrittr)
library(dplyr)

binwidth <- 30

mtcars.stats <- mtcars %>%
  group_by(cyl) %>%
  mutate(bin = cut(hp, breaks=seq(0,400, binwidth), 
               labels= seq(0+binwidth,400, binwidth)-(binwidth/2)),
         n = n()) %>%
  group_by(cyl, bin) %>%
  summarise(p = n()/n[1]) %>%
  ungroup() %>%
  mutate(bin = as.numeric(as.character(bin)))

ggplot(mtcars.stats, aes(x = bin, y= p)) +  
  geom_col() + 
  scale_y_continuous(labels = percent) +
  facet_grid(cyl~.)


这是情节:



#7 楼

如果要使用百分比标签,但要在y轴上使用实际Ns,请尝试以下操作:

    library(scales)
perbar=function(xx){
      q=ggplot(data=data.frame(xx),aes(x=xx))+
      geom_bar(aes(y = (..count..)),fill="orange")
       q=q+    geom_text(aes(y = (..count..),label = scales::percent((..count..)/sum(..count..))), stat="bin",colour="darkgreen") 
      q
    }
    perbar(mtcars$disp)


#8 楼

请注意,如果变量是连续的,则必须使用geom_histogram(),因为该函数将按“ bins”将变量分组。
df <- data.frame(V1 = rnorm(100))

ggplot(df, aes(x = V1)) +  
  geom_histogram(aes(y = 100*(..count..)/sum(..count..))) 

# if you use geom_bar(), with factor(V1), each value of V1 will be treated as a
# different category. In this case this does not make sense, as the variable is 
# really continuous. With the hp variable of the mtcars (see previous answer), it 
# worked well since hp was not really continuous (check unique(mtcars$hp)), and one 
# can want to see each value of this variable, and not to group it in bins.
ggplot(df, aes(x = factor(V1))) +  
  geom_bar(aes(y = (..count..)/sum(..count..))) 


评论


很好的解决方案。但是您忘记乘以100来获得%,即geom_histogram(aes(y = 100 *(.. count ..)/ sum(.. count ..))))。

–drT
12月14日10:58

对。我正在编辑答案。

– Rtist
12月15日下午5:24