【问题标题】:Shortening codes for aggregation and plot聚合和绘图的缩短代码
【发布时间】:2021-09-30 18:34:03
【问题描述】:

我有这样的数据:

a=c(2015,2010,2010,2010,2015)

b=c(100,20,50,40,170)

c=c(20,40,10,50,60)

d=cbind(a,b,c)

我想要一个尽可能短的函数来生成下表(计数是基于 a 的总和)并给出输出 plot(ggplot),其中 x 轴是列“a”,每个都有两个条形图(2010 年使用 b 和 c,2015 年使用 b 和 c),y 轴是“计数”:

a count col
2010 110 b
2010 100 c
2015 270 b
2015 80 c

【问题讨论】:

    标签: r function ggplot2 dplyr


    【解决方案1】:

    这并不像 R 中更有经验的人那样简短,但我会这样做:

    library(ggplot2)
    library(tidyr)
    
    a <- c(2015,2010,2010,2010,2015)
    b <- c(100,20,50,40,170)
    c <- c(20,40,10,50,60)
    d <- data.frame(a,b,c)
    joined <- aggregate(d[,c(2,3)], by = list(d$a), FUN = sum)
    
    data_long <- gather(joined, condition, measurement, b,c, factor_key=TRUE)
    colnames(data_long) <- c("year","col", "count")
    
    data_long <- data_long[order(data_long$year, data_long$col),]
    data_long$year <- as.factor(data_long$year)
    data_long$col <- as.factor(data_long$col)
    
    ggplot(data_long, aes(x = year, y = count,fill=col)) +
      geom_bar(stat="identity",position="dodge")
      
    

    【讨论】:

      【解决方案2】:

      一个可能的解决方案:

      library(dplyr)
      library(ggplot2)
      
      a=c(2015,2010,2010,2010,2015)
      b=c(100,20,50,40,170)
      c=c(20,40,10,50,60)
      d=cbind(a,b,c)
      
      d <- as.data.frame(d)
      
      myplot <- function(d)
      {
        d1 <- d %>% 
          group_by(a) %>% 
          summarise(count = sum(b)) %>%
          mutate(col = "b")
        
        d2 <- d %>% 
          group_by(a) %>% 
          summarise(count = sum(c)) %>% 
          mutate(col = "c")
        
        # This is your table
        z <- rbind(d1,d2) %>% 
          arrange(a)
        
        ggplot() +
          geom_bar(data = z, aes(x = a, y = count, fill = col), 
                   position = "dodge", stat = "identity") +
          scale_x_continuous(breaks=unique(a))
      }
      
      myplot(d)
      

      已编辑:

      更短的解决方案:

      library(dplyr)
      library(ggplot2)
      library(purrr)
      
      a=c(2015,2010,2010,2010,2015)
      b=c(100,20,50,40,170)
      c=c(20,40,10,50,60)
      d=cbind(a,b,c)
      
      d <- as.data.frame(d)
      
      myplot <- function(d)
      {
        z <- map_df(c("b","c"),
                    ~ d %>% 
                      group_by(a) %>% 
                      summarise(count = sum(!!sym(.x))) %>%
                      mutate(col = .x))
        
        ggplot() +
          geom_bar(data = z, aes(x = a, y = count, fill = col), 
                   position = "dodge", stat = "identity") +
          scale_x_continuous(breaks=unique(a))
      }
      
      myplot(d)
      

      【讨论】:

      • 非常感谢,这正是我想要的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 1970-01-01
      • 2013-07-15
      相关资源
      最近更新 更多