ggplot2 geom_bar 定位失败
ggplot2 geom_bar position failure
我在 geom_bar
中使用 ..count..
转换并收到警告
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()
这很好用,结果图显示了根据速度分组的方向频率。相关的是,计数最少的速度 class(此处为“[40,60]”)将有 5 个计数。
然而,更高的速度 classes 会导致警告。例如,
FFcut=cut(FF,breaks=seq(0,60,by=15),ordered_result=TRUE,right=FALSE,drop=FALSE)
计数最少的速度 class(现在是“[45,60]”)将只有 3 个计数,ggplot2 会警告
position_stack 要求 x 间隔不重叠
并且该图将显示该类别中的数据沿 x 轴展开。
似乎 5 是一个组要使其正常工作所需的最小大小。
我很想知道这是 stat_bin
(geom_bar
正在使用)中的功能还是错误,或者我是否只是在滥用 geom_bar
。
此外,如有任何解决此问题的建议,我们将不胜感激。
此致
这并没有直接解决问题,因为我也不知道重叠值是怎么回事,但这是一个由 dplyr
提供支持的解决方法,而且最终可能会更加灵活.
无需依靠 geom_bar
来获取切割因子并通过 ..count../sum(..count..)
为您提供份额,您可以轻松地自己预先计算这些份额,然后绘制您的条形图。我个人喜欢对我的数据以及我正在绘制的内容进行这种类型的控制。
首先,我将dir
和FF
放入一个数据框/tbl_df
,然后切割FF
。然后 count
让我按 dir
和 grp
对数据进行分组并计算这两个变量的每个组合的观察次数,然后计算每个 n
的份额n
的总和。我正在使用 geom_col
,它类似于 geom_bar
,但是当您在 aes
.
中有一个 y
值时
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()
发生这种情况是因为 df$dir
是数字,所以 ggplot 对象假定一个连续的 x 轴,美学参数 group
基于唯一已知的离散变量 (fill = grp
) .
因此,当 grp = [45,60)
中根本没有那么多 dir
值时,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
& df$grp
:
ggplot(data=df,
aes(x=dir,
y=(..count..)/sum(..count..),
group = interaction(dir, grp),
fill = grp)) +
geom_bar()
我在 geom_bar
中使用 ..count..
转换并收到警告
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()
这很好用,结果图显示了根据速度分组的方向频率。相关的是,计数最少的速度 class(此处为“[40,60]”)将有 5 个计数。
然而,更高的速度 classes 会导致警告。例如,
FFcut=cut(FF,breaks=seq(0,60,by=15),ordered_result=TRUE,right=FALSE,drop=FALSE)
计数最少的速度 class(现在是“[45,60]”)将只有 3 个计数,ggplot2 会警告
position_stack 要求 x 间隔不重叠
并且该图将显示该类别中的数据沿 x 轴展开。
我很想知道这是 stat_bin
(geom_bar
正在使用)中的功能还是错误,或者我是否只是在滥用 geom_bar
。
此外,如有任何解决此问题的建议,我们将不胜感激。
此致
这并没有直接解决问题,因为我也不知道重叠值是怎么回事,但这是一个由 dplyr
提供支持的解决方法,而且最终可能会更加灵活.
无需依靠 geom_bar
来获取切割因子并通过 ..count../sum(..count..)
为您提供份额,您可以轻松地自己预先计算这些份额,然后绘制您的条形图。我个人喜欢对我的数据以及我正在绘制的内容进行这种类型的控制。
首先,我将dir
和FF
放入一个数据框/tbl_df
,然后切割FF
。然后 count
让我按 dir
和 grp
对数据进行分组并计算这两个变量的每个组合的观察次数,然后计算每个 n
的份额n
的总和。我正在使用 geom_col
,它类似于 geom_bar
,但是当您在 aes
.
y
值时
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()
发生这种情况是因为 df$dir
是数字,所以 ggplot 对象假定一个连续的 x 轴,美学参数 group
基于唯一已知的离散变量 (fill = grp
) .
因此,当 grp = [45,60)
中根本没有那么多 dir
值时,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
& df$grp
:
ggplot(data=df,
aes(x=dir,
y=(..count..)/sum(..count..),
group = interaction(dir, grp),
fill = grp)) +
geom_bar()