【问题标题】:Why is it so hard to make a simple bar plot in R? How can I easily turn a data frame into a barplot?为什么在 R 中制作简单的条形图如此困难?如何轻松地将数据框变成条形图?
【发布时间】:2023-03-13 09:33:01
【问题描述】:

我有一个这样的数据框:

Categories        time a        time b      
Category 1        xxx.xx        xxx.xx
Category 2        xxx.xx        xxx.xx
.                 .             .
.                 .             .
.                 .             .
Category n        xxx.xx        xxx.xx

我想要的只是按类别创建一个简单的时间 a 与时间 b 分组条形图。它不应该超过一行代码和我 5 分钟的时间。我怎么能简单地做到这一点?我看到的所有解决方案都涉及在我绘制图表之前做一大堆移动废话。

【问题讨论】:

  • 你能分享可重复的样本数据吗?当所有值都是xxx.xx 时,很难演示代码。您的时间是数字、时间戳、日期还是其他?
  • 我对你想要的条形图感到困惑。我假设类别在 x 轴上?也许条的高度是时间,用颜色来区分 a 条和 b 条?还是别的什么?

标签: r plot graph bar-chart


【解决方案1】:

您想要的极简解决方案实际上存在于基础 R 中。

考虑这些数据。

> head(dat, 3)
  Categories time.a time.b.
1  Category1  98.59   90.05
2  Category2 133.10  150.26
3  Category3  22.04   75.15

剧情:

barplot(t(dat[-1]), beside=TRUE, ylab="time")

产量

然后您可以根据需要对其进行优化,例如

rownames(dat) <- 1:10
barplot(t(dat[-1]), beside=TRUE, xlab="Categories", ylab="time", col=2:3)
legend("topleft", c("time a", "time b"), col=2:3, pch=15)

产生

数据

dat <- structure(list(Categories = structure(c(1L, 3L, 4L, 5L, 6L, 7L, 
8L, 9L, 10L, 2L), .Label = c("Category1", "Category10", "Category2", 
"Category3", "Category4", "Category5", "Category6", "Category7", 
"Category8", "Category9"), class = "factor"), time.a = c(98.59, 
133.1, 22.04, 10.24, 17.12, 78.21, 115.41, 76.84, 176.09, 73.02
), time.b. = c(90.05, 150.26, 75.15, 7.07, 1.85, 49.03, 7.41, 
152.89, 139.64, 90.98)), class = "data.frame", row.names = c(NA, 
-10L))

【讨论】:

  • 谢谢!这几乎就是我想要的。到目前为止,我已经放弃并重新格式化了 ggplot2 的数据(这实际上非常美观,所以我不太介意),但轻量级的解决方案总是很方便!
  • 其实我是从ggplot2开始的。然而,我发现自己用很多额外的代码(例如网格线、背景材料、糖果颜色)一个接一个地关闭了一个功能,然后注意到基本图给了我想要的东西。但请自行决定。
【解决方案2】:

R 是一种健壮的语言,它可以产生非常丰富的可视化。所有这些功能意味着用户必须有更多的杠杆才能产生他们想要的可视化,这使学习曲线变陡了。更糟糕的是,最流行的 R 可视化库 (ggplot) 的设计方式对于来自更多面向对象语言或电子表格程序的人来说似乎很奇怪。

我制作了一些我认为你想要的东西。

df <- data.frame(cat=c("cat1", "cat2", "cat3", "cat4", "cat5", "cat6", "cat1", "cat2", "cat3", "cat4", "cat5", "cat6"),
             time_type=c("a","a","a","a","a","a","b","b","b","b","b","b"),
             time=c(12.7, 16, 8.6, 13.4, 7.3, 5.5, 6.8, 15, 33, 4.2, 10, 29.5))


head(df) 
        cat   time_type   time
    1   cat1  a           12.7
    2   cat2  a           16.0
    3   cat3  a           8.6   
    4   cat4  a           13.4  
    5   cat5  a           7.3   
    6   cat6  a           5.5   
    7   cat1  b           6.8
    8   cat2  b           15
    9   cat3  b           33
   10   cat4  b           4.2
   11   cat5  b           10
   12   cat6  b           29.5

并生成图表

ggplot(data=df, aes(x=cat, y=time, fill=time_type)) +
  geom_bar(stat="identity", position=position_dodge())

编辑:

您可以像这样从原始数据框生成此数据框

df2 <- data.frame(cat=c("cat1", "cat2", "cat3", "cat4", "cat5", "cat6"),
                 time_a=c(12.7, 16, 8.6, 13.4, 7.3, 5.5),
                 time_b=c(6.8, 15, 33, 4.2, 10, 29.5))
head(df2)

    cat     time_a  time_b
1   cat1    12.7    6.8 
2   cat2    16.0    15.0    
3   cat3    8.6     33.0    
4   cat4    13.4    4.2 
5   cat5    7.3     10.0    
6   cat6    5.5     29.5    

然后,您可以像这样简单地融化您的数据框:

library(reshape2)
df3 <- melt(df2)
df3


cat     variable  value
cat1    time_a    12.7      
cat2    time_a    16.0      
cat3    time_a    8.6       
cat4    time_a    13.4      
cat5    time_a    7.3       
cat6    time_a    5.5       
cat1    time_b    6.8       
cat2    time_b    15.0      
cat3    time_b    33.0      
cat4    time_b    4.2   
cat5    time_b    10.0      
cat6    time_b    29.5  

ggplot(data=df3, aes(x=cat, y=value, fill=variable)) +
  geom_bar(stat="identity", position=position_dodge())

【讨论】:

  • 这也是我对 OP 想要什么的最佳猜测,但如果您向他们展示如何从问题中的数据格式转换为您在回答。
  • 嗯,实际上我刚才花时间熟悉了 ggplot2,它实际上非常好,所以我想我可以处理重新格式化数据的麻烦。我之前想要的主要是避免以任何方式重新格式化原始 data.frame 中的数据。
  • 我已经编辑了我的回复,以展示如何轻松地将您的数据重新格式化为我在条形图中使用的结构。
猜你喜欢
  • 2018-08-22
  • 2021-07-17
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 2020-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多