我有一个从1到40K的十进制数字列表,我正在尝试绘制频率直方图以及给定bin
的总和。我正在尝试使用ggplot2
来做到这一点,但是却迷失了如何使用直方图中的相同x轴仓:
sales <- data.frame(amount = runif(100, min=0, max=40000))
h <- hist(sales$amount, breaks=b)
sales$groups <- cut(sales$amount, breaks=h$breaks)
ggplot(sales,aes(x=groups)) +
geom_bar(stat="count")+
geom_bar(aes(x=groups, y=amount), stat="identity") +
scale_y_continuous(sec.axis = sec_axis(~.*5, name = "sum"))
我设法分别创建了两个图,但是它们似乎互相覆盖。
或
答案 0 :(得分:1)
如果我理解正确,您尝试在条形图中绘制两个不同的变量(计数和总和)。由于它们的范围确实不同,因此需要定义辅助y轴。
首先,ggplot2
的语法要求x值的一列,y值的一列和组的一列或几列(我对我对如何ggplot2
有效)。
在这里,想法是将“中断”作为x变量,将第二列包含所有y值进行绘制,并指定一组y值是否属于“ Count”或“ amount”组。您可以使用dplyr
和tidyr
软件包来实现此目的:
set.seed(123)
sales <- data.frame(amount = runif(100, min=0, max=40000))
b = 4
h <- hist(sales$amount, breaks=b)
sales$groups <- cut(sales$amount, breaks=h$breaks)
library(tidyr)
library(dplyr)
sales %>% group_by(groups) %>% mutate(Count = n()) %>%
pivot_longer(.,cols = c(Count, amount), names_to = "Variable", values_to = "Value")
# A tibble: 200 x 3
# Groups: groups [4]
groups Variable Value
<fct> <chr> <dbl>
1 (1e+04,2e+04] Count 27
2 (1e+04,2e+04] amount 11503.
3 (3e+04,4e+04] Count 27
4 (3e+04,4e+04] amount 31532.
5 (1e+04,2e+04] Count 27
6 (1e+04,2e+04] amount 16359.
7 (3e+04,4e+04] Count 27
8 (3e+04,4e+04] amount 35321.
9 (3e+04,4e+04] Count 27
10 (3e+04,4e+04] amount 37619.
# … with 190 more rows
但是,如果您试图绘制此笔直的直线,则会得到一个不好的图,其中“ Count”的条形比“ amount”的条形小:
library(ggplot2)
library(tidyr)
library(dplyr)
sales %>% group_by(groups) %>% mutate(Count = n()) %>%
pivot_longer(.,cols = c(Count, amount), names_to = "Variable", values_to = "Value")%>%
ggplot(aes(x=groups, y = Value, fill = Variable)) +
geom_bar(stat="identity", position = position_dodge())
因此,您可以尝试使用sec.axis
中的scale_y_continuous
参数传递辅助y轴。但是,这不会改变您的图,它只会创建一个“伪”右轴,并通过您在参数sec.axis
上传递的值来修改比例尺:
因此,如果要使两组值在图形上可见,则需要按比例缩小“数量”或按比例放大“计数”,以使两组都具有相似的值范围。
在这里,由于您希望在右轴上具有总和,因此我们将按比例缩小“总和”,以便获得与“计数”值相同范围内的值。
在图形上,您可以看到“数量”值达到40000左右,而“计数”的最大值为30。因此,您可以选择以下比例因子:40000/30 = 1333.333。
因此,现在,如果您创建第二个称为“金额”的列,该列是“金额”除以1300的结果,则“金额”和“计数”将处于同一范围内。因此,您的数据现在看起来像这样:
library(dplyr)
library(tidyr)
sales %>% group_by(groups) %>% mutate(Count = n()) %>%
mutate(Amount = amount /1300) %>%
pivot_longer(.,cols = c(Count, Amount), names_to = "Variable", values_to = "Value")
# A tibble: 200 x 4
# Groups: groups [4]
amount groups Variable Value
<dbl> <fct> <chr> <dbl>
1 24000. (2e+04,3e+04] Count 30
2 24000. (2e+04,3e+04] Amount 18.5
3 13313. (1e+04,2e+04] Count 30
4 13313. (1e+04,2e+04] Amount 10.2
5 19545. (1e+04,2e+04] Count 30
6 19545. (1e+04,2e+04] Amount 15.0
7 38179. (3e+04,4e+04] Count 20
8 38179. (3e+04,4e+04] Amount 29.4
9 19316. (1e+04,2e+04] Count 30
10 19316. (1e+04,2e+04] Amount 14.9
# … with 190 more rows
为了使次要y轴反映“数量”值的真实性,可以传递相反的比例因子并将其乘以1300。
总共,您将获得以下代码:
library(ggplot2)
library(dplyr)
library(tidyr)
sales %>% group_by(groups) %>% mutate(Count = n()) %>%
mutate(Amount = amount /1300) %>%
pivot_longer(.,cols = c(Count, Amount), names_to = "Variable", values_to = "Value") %>%
ggplot(aes(x=groups, y = Value, fill = Variable)) +
geom_bar(stat="identity", position = position_dodge()) +
scale_y_continuous(name = "Count",sec.axis = sec_axis(~.*1300, name = "Sum"))
因此,您有一种幻想,可以在两个不同的比例尺上绘制两组不同的值。
希望这个详尽的说明对您有所帮助。