【问题标题】:Horizontal bar plot with both stack and cluster bars in RR中带有堆栈和簇条的水平条形图
【发布时间】:2020-12-01 21:57:25
【问题描述】:

我正在尝试创建一个水平条形图,其中每个变量都有两个条形图。第一个应该是带有正负值计数的堆栈栏,第二个应该是中性值。到目前为止,我还没有做到这一点。 以下是数据示例:

df <- read.table(text = "Positive Negative Neutral
A 4 5 1
B 6 8 3
C 12 3 6
D 10 5 2
E 2 11 7", header = TRUE)

这里是我打算做的情节(用 Excel 制作):

编辑:

感谢大家的帮助!我已经得到了很好的反馈。 我计划继续使用@Duck 提供的选项,因为我觉得ggplot2 更灵活。但是,我想我还想补充(和学习)一件事:

  • 根据正值的数量自动重新排序 y 轴值(id (A, B, C, D, E))(我编辑了上面的图)。例如在这种情况下是 C、D、B、A、E):

我尝试使用reorder()factors(),但没有成功。它应该应用于数据还是直接应用于ggplot?到目前为止我找到的解决方案没有这种双级变量的情况(这里是变量的名称(id)和标志(TRUE =正/负,FALSE =中性)。

【问题讨论】:

    标签: r bar-chart


    【解决方案1】:

    这些天我可能是地球上唯一使用 base R 绘图的人,但对于像这样的非标准绘图,它实际上非常灵活。

    xl <- c(0,20)
    cols <- c("blue","orange","grey")
    
    bd <- t(as.matrix(df))
    bp <- barplot(unname(bd[1:2, rbind(1:5,NA,NA)]), xlim=xl, horiz=TRUE, col=cols[1:2])
          barplot(unname(bd[3,   rbind(NA,1:5,NA)]), xlim=xl, horiz=TRUE, col=cols[3],
                  axes=FALSE, add=TRUE)
    axis(2, at=colMeans(matrix(bp, nrow=3)[1:2,]), labels=colnames(bd), las=1, lty=0)
    par(xpd=NA)
    legend("bottom", rownames(bd), fill=cols, horiz=TRUE, inset=-1 / par("pin")[2], bty="n")
    

    结果:

    【讨论】:

    • 也感谢您添加此选项!如果我不管理如何使用 ggplot2 重新排序变量,我会选择这个
    【解决方案2】:

    尝试使用这样的方面并巧妙地创建一个引用变量来创建两个变量并使用ggplot2 和一些tidyverse 函数绘制它们:

    library(ggplot2)
    library(tidyverse)
    #Data
    df %>% rownames_to_column("id") %>%
      pivot_longer(-id) %>%
      mutate(Flag=name %in% c('Positive','Negative')) %>%
      ggplot(aes(x=Flag,y=value,fill=name))+
      geom_bar(stat = 'identity')+
      facet_grid(id~., switch = "y") +
      scale_fill_manual(values = c("red", "tomato", "cyan3"), name = "") +
      coord_flip() +
      theme_classic() +
      theme(panel.spacing = unit(0, "points"),
            strip.background = element_blank(),
            axis.text.y = element_blank(),
            axis.ticks.length.y = unit(0, "points"),
            axis.title = element_blank(),
            strip.placement = "outside",
            strip.text = element_text(),
            legend.position = "bottom",
            panel.grid.major.x = element_line())
    

    输出:

    更新:为了获得所需的顺序,您可以创建一个虚拟数据来对标签进行排序,然后将 id 变量格式化为因子。代码如下:

    #Auxiliar data
    levs <- df %>% rownames_to_column("id") %>%
      pivot_longer(-id) %>%
      filter(name=='Positive') %>%
      arrange(desc(value))
    #Data
    df %>% rownames_to_column("id") %>%
      pivot_longer(-id) %>%
      mutate(Flag=name %in% c('Positive','Negative'),
             id=factor(id,levels = levs$id,ordered = T)) %>%
      ggplot(aes(x=Flag,y=value,fill=name))+
      geom_bar(stat = 'identity')+
      facet_grid(id~., switch = "y") +
      scale_fill_manual(values = c("red", "tomato", "cyan3"), name = "") +
      coord_flip() +
      theme_classic() +
      theme(panel.spacing = unit(0, "points"),
            strip.background = element_blank(),
            axis.text.y = element_blank(),
            axis.ticks.length.y = unit(0, "points"),
            axis.title = element_blank(),
            strip.placement = "outside",
            strip.text = element_text(),
            legend.position = "bottom",
            panel.grid.major.x = element_line())
    

    输出:

    【讨论】:

    • 非常感谢,这看起来和工作都很棒(并且只需一个代码)!基本上它是关于创造“条件”(就像你对“变异”所做的那样)是否是“积极/消极”。
    • 如果想订购条形,例如通过具有更多正值的 id?我尝试了 '''mutate(Flag = reorder(Flag, value == "Positive"))''' 和 '''ggplot(aes(x = reorder(Flag, -value == "Positive"),y =value,fill=effect)''' 但它不起作用。
    • @FTc 我已经添加了你想要的更新。让我知道这是否对您有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 2013-05-15
    相关资源
    最近更新 更多