【问题标题】:Plotting binned data using sum instead of count使用 sum 而不是 count 绘制分箱数据
【发布时间】:2017-05-15 13:00:30
【问题描述】:

我试图寻找答案,但似乎找不到合适的答案。

我有一个数据集 (data),其中包含两个变量:人们的年龄 (age) 和奖项数量 (awards)

我的目标是在 R.FYI 中绘制奖项数量与年龄的关系,一个人可以有多个奖项,而且人们可以有相同的年龄。

我尝试绘制直方图和条形图,但这样做的问题是它计算观察次数而不是对奖励次数求和。

样本数据集:

age <- c(21,22,22,25,30,34,45,26,37,46,49,21)
awards <- c(0,3,2,1,0,0,1,3,1,1,1,1)
data <- data.frame(cbind(age,awards))

我正在寻找的是代表此数据的直方图(或条形图)。

理想情况下,我希望将年龄分成年龄组。例如, 20-30、31-40、41-50,然后是每组的获奖总数。

x 轴为年龄组,y 轴为每个年龄组的奖励总数。

谢谢!

【问题讨论】:

  • 到目前为止您尝试过什么?因为SO上已经有类似的问题了
  • “人”如何在这里发挥作用?
  • 也分享dput(data)而不是图片

标签: r histogram bar-chart data-visualization


【解决方案1】:

我们可以使用aggregate 函数,然后使用ggplot2 包。这些天我没有在基础R 中制作太多条形图,所以我不确定不加载ggplot2 的最佳方法:

创建示例数据

#data
set.seed(123)
dat <- data.frame(age = sample(20:50, 200, replace = TRUE),
                  awards = rpois(200, 3))
head(dat)
  age awards
1  28      2
2  44      6
3  32      3
4  47      3
5  49      2
6  21      5

按年龄

#aggregate

sum_by_age <- aggregate(awards ~ age, data = dat, FUN = sum)

library(ggplot2)

ggplot(sum_by_age, aes(x = age, y = awards))+
    geom_bar(stat = 'identity')

按年龄组

#create groups

dat$age_group <- ifelse(dat$age <= 30, '20-30',
                        ifelse(dat$age <= 40, '30-40',
                               '41 +'))

sum_by_age_group <- aggregate(awards ~ age_group, data = dat, FUN = sum)

ggplot(sum_by_age_group, aes(x = age_group, y = awards))+
    geom_bar(stat = 'identity')

注意

我们可以完全跳过aggregate 步骤,直接使用:

ggplot(dat, aes(x = age, y = awards)) + geom_bar(stat = 'identity')

但我不喜欢这种方式,因为我认为在您的分析管道中使用中间数据步骤可能对比较有用,而不是进行可视化。

【讨论】:

  • 不错的答案,但您可能希望将底部组更改为 &lt;= 30,因为代码会将小于 30 的任何内容放在底部括号中。
【解决方案2】:

为了完整起见,我将基础R 解决方案添加到@bouncyball 的最佳答案中。我将使用他们的合成数据,但我将使用cut 在聚合之前创建年龄组。

# Creates data for plotting
> set.seed(123)
> dat <- data.frame(age = sample(20:50, 200, replace = TRUE),
                    awards = rpois(200, 3))

# Created a new column containing the age groups
> dat[["ageGroups"]] <- cut(dat[["age"]], c(-Inf, 20, 30, 40, Inf),
                            right = FALSE)

cut 将根据第二个参数中定义的中断划分一组数字数据。 right = FALSE 翻转中断,因此这些组的值将包括较低的值而不是较高的值(即20 &lt;= x &lt; 30 而不是20 &lt; x &lt;= 30 的默认值)。这些组不必等间距。如果您不想包含高于或低于某个值的数据,只需分别从末尾删除Inf 或从开头删除-Inf,函数将返回&lt;NA&gt;。如果您想为您的组命名,可以使用 labels 参数。

现在我们可以根据我们创建的组aggregate

> (summedGroups <- aggregate(awards ~ ageGroups, dat, FUN = sum))
  ageGroups awards
1   [20,30)    188
2   [30,40)    212
3 [40, Inf)    194

最后,我们可以使用barplot 函数绘制这些数据。这里的关键是针对年龄组使用names

> barplot(summedGroups[["awards"]], names = summedGroups[["ageGroups"]])

【讨论】:

  • @bouncyball 谢谢,我进行了编辑并决定使用right = TRUE 参数,因为这似乎更接近用户想要的,我提到labels 参数是一个选项。
  • 很公平,感谢您展示基本的R 实现
猜你喜欢
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-14
  • 2011-02-03
  • 1970-01-01
  • 2017-07-31
  • 1970-01-01
相关资源
最近更新 更多