我在..count..
中使用geom_bar
转换并获得警告
当某些类别的计数很少时, position_stack需要不重叠的x区间。
最好使用一些模拟数据解释(我的数据涉及方向和风速,我保留与之相关的名称)
#make data
set.seed(12345)
FF=rweibull(100,1.7,1)*20 #mock speeds
FF[FF>60]=59
dir=sample.int(10,size=100,replace=TRUE) # mock directions
#group into speed classes
FFcut=cut(FF,breaks=seq(0,60,by=20),ordered_result=TRUE,right=FALSE,drop=FALSE)
# stuff into data frame & plot
df=data.frame(dir=dir,grp=FFcut)
ggplot(data=df,aes(x=dir,y=(..count..)/sum(..count..),fill=grp)) + geom_bar()
这很好用,结果图显示了根据速度分组的方向的频率。具有最小计数的速度等级(此处为“[40,60”“)将具有5个计数是相关的。
然而,更多速度等级会导致警告。例如,
FFcut=cut(FF,breaks=seq(0,60,by=15),ordered_result=TRUE,right=FALSE,drop=FALSE)
具有最少计数的速度等级(现在为“[45,60)”)将只有3个计数,而ggplot2将警告
position_stack需要不重叠的x区间
并且该图将显示沿x轴展开的此类别中的数据。 似乎5是一个组正常工作的最小大小。
我很想知道这是stat_bin
中的一个功能或错误(geom_bar
正在使用)还是我只是在滥用geom_bar
。
此外,任何建议如何解决这个问题将不胜感激。
真诚
答案 0 :(得分:5)
这是因为df$dir
是数字,因此ggplot对象假设一个连续的x轴,而美学参数group
基于唯一已知的离散变量(fill = grp
)。 / p>
因此,当dir
中的grp = [45,60)
值不是很多时,ggplot会对每个条的宽度感到困惑。如果我们将情节分成不同的方面,这在视觉上会变得更加明显:
ggplot(data=df,
aes(x=dir,y=(..count..)/sum(..count..),
fill = grp)) +
geom_bar() +
facet_wrap(~ grp)
> for(l in levels(df$grp)) print(sort(unique(df$dir[df$grp == l])))
[1] 1 2 3 4 6 7 8 9 10
[1] 1 2 3 4 5 6 7 8 9 10
[1] 2 3 4 5 7 9 10
[1] 2 4 7
我们还可以手动检查排序的df$dir
值之间的最小差异对于前三个grp
值是1,而对于最后一个值是2。因此,默认条宽度更宽。
以下解决方案都应达到相同的效果:
<强> 1。为geom_bar()
中的所有群组明确指定相同的条形宽度:
ggplot(data=df,
aes(x=dir,y=(..count..)/sum(..count..),
fill = grp)) +
geom_bar(width = 0.9)
<强> 2。将dir
转换为分类变量,然后再将其传递给aes(x = ...)
:
ggplot(data=df,
aes(x=factor(dir), y=(..count..)/sum(..count..),
fill = grp)) +
geom_bar()
第3。指定group
参数应基于df$dir
和&amp; df$grp
强>:
ggplot(data=df,
aes(x=dir,
y=(..count..)/sum(..count..),
group = interaction(dir, grp),
fill = grp)) +
geom_bar()
答案 1 :(得分:1)
这并没有直接解决问题,因为我也没有得到重叠值的结果,但它是一个dplyr
驱动的解决方法,无论如何可能会变得更灵活。 / p>
不是依靠geom_bar
来获取削减因子并通过..count../sum(..count..)
为您提供分享,您可以轻松地预先自己计算这些份额,然后绘制条形图。我个人喜欢对我的数据进行这种控制,以及我正在绘制的内容。
首先,我将dir
和FF
放入数据框/ tbl_df
,然后剪切FF
。然后count
允许我按dir
和grp
对数据进行分组,并计算这两个变量的每个组合的观察数,然后计算每个n
的份额n
的总和。我正在使用geom_col
,就像geom_bar
,但当y
中有aes
值时。
library(tidyverse)
set.seed(12345)
FF <- rweibull(100,1.7,1) * 20 #mock speeds
FF[FF > 60] <- 59
dir <- sample.int(10, size = 100, replace = TRUE) # mock directions
shares <- tibble(dir = dir, FF = FF) %>%
mutate(grp = cut(FF, breaks = seq(0, 60, by = 15), ordered_result = T, right = F, drop = F)) %>%
count(dir, grp) %>%
mutate(share = n / sum(n))
shares
#> # A tibble: 29 x 4
#> dir grp n share
#> <int> <ord> <int> <dbl>
#> 1 1 [0,15) 3 0.03
#> 2 1 [15,30) 2 0.02
#> 3 2 [0,15) 4 0.04
#> 4 2 [15,30) 3 0.03
#> 5 2 [30,45) 1 0.01
#> 6 2 [45,60) 1 0.01
#> 7 3 [0,15) 6 0.06
#> 8 3 [15,30) 1 0.01
#> 9 3 [30,45) 2 0.02
#> 10 4 [0,15) 6 0.06
#> # ... with 19 more rows
ggplot(shares, aes(x = dir, y = share, fill = grp)) +
geom_col()