【问题标题】:Create percentage labels for two discrete variables in ggplot 2 [duplicate]在ggplot 2中为两个离散变量创建百分比标签[重复]
【发布时间】:2021-08-19 13:18:51
【问题描述】:

这是一些示例数据:

gender <- c("male", "female", "male", "male", "female", "female", "male", "female", "female", "male")
outcome <- factor(c(0,0,0,1,1,1,0,1,1,1), levels = c(0,1), labels = c("responders", "non-responders"))      
df <- c(gender, outcome)

我希望创建一个 ggplot,其中 y 轴是百分比,x 轴是性别,填充是结果。它必须是一个带有百分比标签的堆叠条。

在这里试过这个代码:

ggplot (df, aes (x = 性别, fill = 结果)) + geom_bar()

但这给了我 y 轴的计数。我希望在 y 轴上创建百分比。堆叠的女性条必须指示“女性组内有反应者和无反应者结果”的女性百分比,而不是总人口中有反应或没有反应的女性百分比。例如,我希望看到 40% 的女性响应者与 60% 的无响应者以及男性的类似情况。

为了准备好发布,我还需要在堆叠栏中添加这些百分比的标签。

【问题讨论】:

    标签: r ggplot2 stacked-chart


    【解决方案1】:

    这里是标签:

    library(ggplot2)
    gender <- c("male", "female", "male", "male", "female", "female", "male", "female", "female", "male")
    outcome <- factor(c(0,0,0,1,1,1,0,1,1,1),  labels = c("responders", "non-responders"))      
    df <- data.frame(gender, outcome)
    
    ggplot(df, aes(x= gender)) + 
      geom_bar(aes(y = 2*(..count..)/sum(..count..), fill = outcome, group=outcome), stat="count") +
      geom_label(aes(label = scales::percent(2*(..count..)/sum(..count..)),
                      group = outcome), position = "fill", stat= "count", vjust = 0) +
      labs(y = "Percent", fill="outcome") +
      scale_y_continuous(labels = scales::percent)
    

    看来@Paul 对geom_bar 有更好的办法。

    编辑

    这是一个通用的解决方案:

    library(ggplot2)
    gender <- c("female", "female", "male", "male", "female", "female", "male", "female", "female", "male")
    outcome <- factor(c(0,0,0,1,1,1,0,1,1,1),  labels = c("responders", "non-responders"))      
    df <- data.frame(gender, outcome)
    
    gg <- ggplot() + 
      geom_bar(aes(x= gender, fill = outcome), data = df, position = "fill")
    ggb <- ggplot_build(gg)
    df2 <- data.frame(y = ggb$data[[1]][["y"]])
    
    gg + geom_label(
      aes(x = rep(c(1,2), each = 2), label = scales::percent(y), y = y), 
      data = df2
    )
    

    【讨论】:

    • 感谢您的回复,但是,这与我想要的略有不同。我将编辑我的问题以使其更清楚。但我希望显示“男性”和“女性”的百分比,而不是总数的百分比。例如。 40% 的女性是响应者,60% 是非响应者,显示在“女性”堆栈中。
    • @Pashtun 我编辑了。
    • @StéphaneLaurent 你的回答更好地处理了标记条,我仍然很难让它工作:p
    • @Paul 我不喜欢2*,因为它的工作原理是男性多于女性。
    • @StéphaneLaurent 感谢您编辑您的答案。这是一个很好的补充,但是,正如您自己指出的那样,女性/男性在示例数据集中完全相同,但在我的真实数据集中却不同,这为标签提供了错误的值。因为我有很多情节要制作(20+),所以如果有一个“通用代码”可以使用而不是手动计算男性:女性之间的比例(这将根据结果的可用数据而有所不同),那就太好了。
    【解决方案2】:

    不必更改数据的诀窍是使用geom_bar(position = "fill"),如下所述:https://stackoverflow.com/a/48602277/10264278。 要格式化 y 轴的标签,您有多种选择。以下是其中两个:

    • 使用scales 包scales::percent_format()
    • 改用自定义函数,只需将上面的代码替换为function(x) paste0(x*100, "%")

    这里是:

    gender <- c("male", "female", "male", "male", "female", "female", "male", "female", "female", "male")
    outcome <- factor(c(0,0,0,1,1,1,0,1,1,1), levels = c(0,1), labels = c("responders", "non-responders"))      
    df <- data.frame(gender, outcome)
    
    library(ggplot2)
    ggplot(data = df, aes(x = gender, fill = outcome)) +
      geom_bar(position="fill") +
      scale_y_continuous(labels = function(x) paste0(x*100, "%"))
    

    由reprex package (v2.0.0) 于 2021-08-19 创建

    【讨论】:

    • 这是一个很好的答案,谢谢!效果很好。尝试支持它,但说我需要至少 15 个声望。是否也可以将百分比显示为标签?
    【解决方案3】:

    设法找到 Paul 和 Stéphane 发布的替代工作答案(两者都很棒)。这种方法的优点是通用性强,创建很多地块时可以节省时间。

    library(dplyr)
    library(ggplot2)
    
    gender <- c("male", "female", "male", "male", "female", "female", "male", "female", "female", "male")
    outcome <- factor(c(0,0,0,1,1,1,0,1,1,1), levels = c(0,1), labels = c("responders", "non-responders"))      
    df <- data.frame(gender, outcome)
    
    df %>%
      group_by(gender, outcome) %>% 
      summarise(count = n()) %>% 
      mutate(pct = round(count/sum(count), 2)) %>%
    ggplot(aes(x = factor(gender), y = pct, fill = factor(outcome))) +
      geom_bar(stat="identity", width = 0.7) + scale_y_continuous(labels = scales::percent_format()) +
      labs(x = "Sex", y = "Percentage", fill = "Outcome") +
      theme_minimal(base_size = 14) +
      geom_text(aes(label=paste0(pct*100, "%")), vjust=-0.25, position=position_stack(0.5))
    

    这是输出

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      • 2021-10-14
      • 1970-01-01
      • 2020-04-18
      • 2023-04-08
      • 2018-08-04
      • 1970-01-01
      相关资源
      最近更新 更多