【问题标题】:R - Weighting by group size in bar chartsR - 在条形图中按组大小加权
【发布时间】:2017-03-24 19:57:28
【问题描述】:

假设我有一个如下所示的数据框:

groups <- floor(runif(1000, min=1, max=5))
activity <- rep(c("A1", "A2", "A3", "A4"), times= 250)
endorsement <- floor(runif(1000, min=0, max=2))
value1 <- runif(1000, min=1, max=10)
area <- rep(c("A", "A", "A", "A", "B", "C", "C", "D", "D", "E"), times = 100)

df <- data.frame(groups, activity, endorsement, value1, area)

印刷:

> head(df)
  groups activity endorsement   value1 area
1      1       A1           0 7.443375    A
2      1       A2           0 4.342376    A
3      1       A3           0 4.810690    A
4      4       A4           0 3.494974    A
5      3       A1           1 6.442354    B
6      1       A2           0 9.794138    C

我想计算一些描述性统计数据并创建一些条形图,但是如果您查看 area 变量,A 的表示非常好,而 BE 则没有。

我对 area 变量本身不感兴趣,但统计/绘图将由数据集中具有高代表性的区域驱动,因此我需要对数据进行加权,但我不确定正确的方法在以下情况下这样做:

平均值和标准差

我正在计算平均值和 SD 或 value1,如下所示:

df %>% group_by(groups) %>% summarise(mean=mean(value1), sd=sd(value1))

计算加权平均值/标准差以补偿每个区域的样本量差异的正确方法是什么(即我想给每个 area 同等权重)?

堆积条形图

ggplot(df, aes(groups)) +
  geom_bar(aes(fill = activity), position = position_fill(reverse = F))

这些条形代表每个activity 在每个group 中出现的频率比例。同样,这主要是由来自 A 区的受访者推动的 - 有没有办法平衡这一点并计算比例,就好像 area 具有相同的代表性?

分组表示

ggplot(aes(x = activity, y = value1, fill=factor(groups)), data=df) +
  geom_bar(position="dodge", stat="summary", fun.y="mean")+
  guides(fill = guide_legend(reverse=F, title="group"))

这些条形代表每个 groupactivity 组合的 value1 的平均值。同样,这些平均值的权重有利于区域 A,并且代表性不相等

分组计数比例

summary_df <- df %>% group_by(groups, activity) %>%
    summarise(n=n(), count=sum(endorsement)) %>% mutate(prop=(count/n)*100)

ggplot(aes(x = activity, y = prop, fill = factor(groups)), data=summary_df) +
  geom_bar(width=0.8, position = position_dodge(width=0.8), stat="identity") +
  guides(fill = guide_legend(reverse=F, title="group"))

对于每个 groupactivity 组合,我正在计算支持该项目的人数(回复 1),并计算子组中总人数的比例

以上 4 个问题都源于同一个问题,都需要用area 加权以创建相等的表示。但是,可视化的创建方式都不同,并且显示了不同的内容(平均值、堆叠条、分组平均值、计数比例),我不确定在每种情况下考虑样本量差异的正确方法。是否有一个修复将传播到每个图形示例?

【问题讨论】:

    标签: r plot ggplot2 data-visualization weighted-average


    【解决方案1】:

    一种策略是 down-up-sample 您的 dataframe,以便每个区域具有相同数量的观察值。我们可以使用caret 包中的便利函数downSample()upSample(),根据文档:

    “简单随机抽样用于对多数类进行下采样。请注意,少数类数据保持不变......”

    举例说明:

    library(dpyr)
    library(caret)
    # Before
    df %>% group_by(area) %>% summarise(n())
    #   area `n()`
    #1      A   400
    #2      B   100
    #3      C   200
    #4      D   200
    #5      E   100
    
    # After
    set.seed(123)
    test_down <- downSample(df, df$area)
    test_down %>% group_by(area) %>% summarise(n())
    #    area `n()`
    #1      A   100
    #2      B   100
    #3      C   100
    #4      D   100
    #5      E   100
    
    test_up <- upSample(df, df$area)
    test_up %>% group_by(area) %>% summarise(n())
    #    area `n()`
    #1      A   400
    #2      B   400
    #3      C   400
    #4      D   400
    #5      E   400
    

    那么你的第一张图就变成了:

    library(ggplot2)
    ggplot(test_down, aes(groups)) +
            geom_bar(aes(fill = activity), 
                     position = position_fill(reverse = F))
    

    请注意,由于我们使用随机抽样,因此我们无法控制在使用 downSample() 时会忽略哪些观察结果。因此,在没有set.seed() 的情况下,每次运行的结果可能会略有不同。

    【讨论】:

    • 谢谢。除了下采样还有其他选择吗?因为area 的分布非常不平衡——一些区域的数据几乎是其他区域的 100 倍,所以下采样意味着我们会从过度代表的区域中损失很多
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 2022-08-02
    • 1970-01-01
    相关资源
    最近更新 更多