【问题标题】:Create stacked barplot where each stack is scaled to sum to 100%创建堆叠条形图,其中每个堆栈都缩放为总和为 100%
【发布时间】:2012-03-22 17:33:05
【问题描述】:

我有一个这样的data.frame:

df <- read.csv(text = "ONE,TWO,THREE
                       23,234,324
                       34,534,12
                       56,324,124
                       34,234,124
                       123,534,654")

我想制作一个看起来像这样的百分比条形图(在 LibreOffice Calc 中制作):

因此,条形应该标准化,以便所有堆栈具有相同的高度并且总和为 100%。到目前为止,我所能得到的只是一个堆叠的条形图(不是百分比),使用:

barplot(as.matrix(df))

有什么帮助吗?

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    您只需将每个元素除以其列中值的总和即可。

    这样做就足够了:

    data.perc <- apply(data, 2, function(x){x/sum(x)})
    

    请注意,第二个参数告诉apply 将提供的函数应用于列(使用 1 您会将其应用于行)。然后,匿名函数每次传递一个数据列。

    【讨论】:

    • 您好,这并没有调整我的数据,rowSums(data.perc) 不是每行 1。相反,我使用了这个:data.perc &lt;- apply(data, 2, function(x){x/(apply(data,1,sum))})
    • 您是否有 NA 或零和线?否则我不太明白为什么那行不通......
    【解决方案2】:

    prop.table 是一种很好的获取表格比例的友好方式。

    m <- matrix(1:4,2)
    
     m
         [,1] [,2]
    [1,]    1    3
    [2,]    2    4
    

    留空边距为您提供整个表格的比例

     prop.table(m, margin=NULL)
         [,1] [,2]
    [1,]  0.1  0.3
    [2,]  0.2  0.4
    

    给它 1 给你行比例

     prop.table(m, 1)
          [,1]      [,2]
    [1,] 0.2500000 0.7500000
    [2,] 0.3333333 0.6666667
    

    而2是列比例

     prop.table(m, 2)
              [,1]      [,2]
    [1,] 0.3333333 0.4285714
    [2,] 0.6666667 0.5714286
    

    【讨论】:

      【解决方案3】:

      这是一个使用 ggplot 包(版本 3.x)的解决方案,以及您目前所获得的解决方案。

      我们将geom_barposition 参数设置为position = "fill"。如果要使用position_fill() 的参数(vjustreverse),也可以使用position = position_fill()

      请注意,您的数据是“宽”格式,而ggplot2 要求它是“长”格式。因此,我们首先需要gather 数据。

      library(ggplot2)
      library(dplyr)
      library(tidyr)
      
      dat <- read.table(text = "    ONE TWO THREE
      1   23  234 324
      2   34  534 12
      3   56  324 124
      4   34  234 124
      5   123 534 654",sep = "",header = TRUE)
      
      # Add an id variable for the filled regions and reshape
      datm <- dat %>% 
        mutate(ind = factor(row_number())) %>%  
        gather(variable, value, -ind)
      
      ggplot(datm, aes(x = variable, y = value, fill = ind)) + 
          geom_bar(position = "fill",stat = "identity") +
          # or:
          # geom_bar(position = position_fill(), stat = "identity") 
          scale_y_continuous(labels = scales::percent_format())
      

      【讨论】:

      • melt() 属于哪个包?是reshape2吗?
      • 是的;我很抱歉。这么长时间 ggplot2 自己加载这些包,我已经生锈了。
      • 我尝试使用 reshape 包中的 melt 并收到以下错误:“Scale$labels(breaks) 中的错误:未使用的参数 (s) (breaks)”我想知道是不是因为我我正在从 csv 读取数据。
      • @JulioDiaz 嗯。很难说发生了什么,特别是如果您正在使用的数据看起来与您问题中的示例不完全相同。我会确保所有软件包都是最新的,并且您使用的是 R 2.14.2(我必须升级到 2.14.2 才能让 ggplot 0.9.0 中的一些东西正常工作)。
      • 对于那些在 2018 年之后使用此功能的用户,请将“labels = percent_format()”替换为“scales::percent”。
      【解决方案4】:

      Chris Beeley 是正确的,您只需要按列的比例。使用您的数据是:

       your_matrix<-( 
                     rbind(
                             c(23,234,324), 
                             c(34,534,12), 
                             c(56,324,124), 
                             c(34,234,124),
                             c(123,534,654)
                          )
                      )
      
       barplot(prop.table(your_matrix, 2) )
      

      给予:

      【讨论】:

      • 这应该是公认的答案。真的很简单,很简单。
      • @kboom 它不使用ggplot2,因此 OP 标记了他的问题
      猜你喜欢
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多