【问题标题】:How to make and customize sections within the bars of a barplot created with ggpplot2?如何在使用 ggpplot2 创建的条形图的条形图中制作和自定义部分?
【发布时间】:2020-07-17 22:37:38
【问题描述】:

我在这里创建了一个类似data 的数据框:

set.seed(123)
data <- data.frame(Loc = paste("Loc", seq(1:20), sep = ""),
                   A = sample(c(0,15,20,25,40),size = 20,replace = T, prob = c(45,25,15,10,5)),
                   B = sample(c(0,15,20,25,40),size = 20,replace = T, prob = c(45,25,15,10,5)),
                   C = sample(c(0,15,20,25,40),size = 20,replace = T, prob = c(45,25,15,10,5))
                   )
data$D <- 100-(data[,2]+data[,3]+data[,4])
data$total <- sample(c(10:20), replace = T, length(data[,1]))

这里,Loc 是一个有 20 个级别的分组变量。每个Loc 代表一个从中获取样本的位置(实际的“样本”不在这里)。 ABCD 表示观测值分配到的集群。 ABCD 列中每个 Loc 的关联值表示分配给每个群集的每个 Loc 的观察百分比。 total 列表示从每个 Loc 获取的观察总数。例如,Loc1 有 14 个观测值,其中 25% 的观测值被分配到集群 B,75% 的观测值被分配到集群 D。 我制作了一个条形图,在 x 轴上显示 Loc,在 y 轴上显示 total。假设每个集群都将被赋予一个唯一的“颜色”,我试图以这样一种方式为条形着色,即对于给定的Loc,颜色将代表分配给每个集群的观察百分比。例如,假设集群B 是黄色,集群D 是蓝色,那么Loc1 的条形将是25% 的黄色和75% 的蓝色。 我已经尝试了几种变体:

library(tidyverse)
data%>%
  pivot_longer(-c(Loc,total), names_to= "Group", values_to = "val")%>%
  ggplot(., aes(x=Loc, y=total, col = Group))+
  geom_bar(stat = "identity", aes(fill = val))+
  geom_text(aes(label = total))

这会产生:

这很接近,但不是我想要的。我怎样才能制作这种情节?如果可能的话,我还想将total 的值移动到每个条的顶部,并将与每种颜色相关联的百分比移动到每个条中“颜色”或“集群”部分的中心。

【问题讨论】:

    标签: r ggplot2 dplyr bar-chart


    【解决方案1】:

    试试这个。我按组添加了一个带有数字的变量。

    library(ggplot2)
    library(dplyr)
    library(tidyr)
    
    set.seed(123)
    data <- data.frame(Loc = paste("Loc", seq(1:20), sep = ""),
                       A = sample(c(0,15,20,25,40),size = 20,replace = T, prob = c(45,25,15,10,5)),
                       B = sample(c(0,15,20,25,40),size = 20,replace = T, prob = c(45,25,15,10,5)),
                       C = sample(c(0,15,20,25,40),size = 20,replace = T, prob = c(45,25,15,10,5))
    )
    data$D <- 100-(data[,2]+data[,3]+data[,4])
    data$total <- sample(c(10:20), replace = T, length(data[,1]))
    
    data1 <- data %>%
      pivot_longer(-c(Loc,total), names_to= "Group", values_to = "val") %>%
      # Number per Group
      mutate(val1 = val * total / 100) 
    
    data1 %>%
      # Map val1 on y, Group on fill
      ggplot(., aes(x=Loc, y=val1, fill = Group))+
      geom_bar(stat = "identity")+
      # Make label only for the first group. Here: A
      geom_text(aes(y = total, label = ifelse(Group == "A", total, "")), nudge_y = 1, size = 3) +
      # Add percentages
      geom_text(aes(y = val1, 
                    label = ifelse(val > 0, scales::percent(val, scale = 1, accuracy = 1), "")), 
                position = position_stack(vjust = .5), size = 3)
    

    【讨论】:

    • 感谢您的回复,这正是我想要完成的。我不熟悉其中一些论点,但我正在努力解决它。您能解释一下在百分比很小(例如 3%)或重叠的情况下我能做什么吗?将其应用于我的真实数据集时,一些百分比相互重叠
    • 啊,我看到 position_stack() 参数可以调整以帮助解决这个问题
    【解决方案2】:

    你可以试试这个:

    library(reshape2)
    library(tidyverse)
    #Format Loc
    data$Loc <- factor(data$Loc,levels = paste0('Loc',1:dim(data)[1]),ordered = T)
    #Melt
    df <- melt(data,id.vars = c('Loc','total'))
    #Create label
    df$Label <- ifelse(df$value==0,NA,paste0(df$value,'%'))
    #Plot
    ggplot(df,aes(x=Loc,y=value,color=variable,group=variable,label=Label,fill=variable))+
      geom_bar(stat='identity')+
      geom_text(position=position_stack(vjust=0.5),color='black')+
      geom_text(inherit.aes = FALSE, data = data, 
                aes(x = Loc, y = 100, label = total), vjust = -0.25)
    

    【讨论】:

    • 谢谢您的回复,但是我想保留不同条形高度的属性来说明每组中的样本数量(高度基于total)你能修改这段代码来完成那个?
    • @Ryan 等一下!
    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 2022-12-10
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    相关资源
    最近更新 更多