【问题标题】:Incrementally building a barplot in R在 R 中逐步构建条形图
【发布时间】:2017-05-28 21:12:07
【问题描述】:

我正在尝试制作一个图表,显示三明治店不同类型三明治的卡路里计数。 IE。 Subway vs Jimmy John's 的素食三明治有多少卡路里。

我想把它想象成一个条形图,那个

  • 每个三明治的卡路里计数都有一个条形

  • 明显按类型对三明治进行分组蔬菜烤牛肉等。供应商。

我的数据看起来像这样(为重现性而编辑):

cleaninput <- data.frame ("type" = c("italian", "turkey", "roastbeef", "club", "veggie", "italian", "turkey", "roastbeef", "veggie"), 
"vendor" = c( "subway",  "subway",  "subway",  "subway",  "subway",  "jimmyjohns", "jimmyjohns", "jimmyjohns", "jimmyjohns"),
"calories" = c(410,280,320,310,230,640,510,540,690))

我尝试像这样迭代数据,其中cleaninput 是我的data.frame

#set up barplot
barplot(height = mean(cleaninput[['calories']]))
#iterate over sandwich types
for (t in levels(cleaninput[['type']]))
{
  cat(t,"\n")

  barplot(cleaninput[cleaninput[['type']]==t,][['calories']], add = TRUE)
}

首先设置条形图,然后迭代地添加每种三明治类型的条形图。我understoodadd 设置来做到这一点。我使用linespoints 命令并复制了下面的示例,对常规绘图做了类似的事情——这就是我想要转移到条形图的内容。

但是,它不起作用,因为它似乎把所有的条都糊在一起了(参见下面的输出)。

我的问题

  • (如何)我可以解决这个问题吗?最好我想使用 base R 而不是 ggplot 来使它更便携。

  • 有没有比for-loop 更好的方法?

我查看了tutorials 的分组条形图,但没有看到它们如何转化为我的问题。

当前输出:

【问题讨论】:

  • 请以可用的形式提供您的数据或其子集——我们可以复制和粘贴而无需进行格式化,例如通过粘贴dput(cleaninput) 的输出。您可能会考虑学习 ggplot2 。 sthda.com/english/wiki/…
  • @R.S.谢谢,我认为我的示例是可复制和可粘贴的,但事实并非如此,我已将其替换为正确的示例。感谢 ggplot 的建议,但正如我上面所说,我想让它在 base 中工作。

标签: r for-loop plot bar-chart


【解决方案1】:

这是根据要求在基图中的解决方案,因为这是您对 ggpltot2 的偏好。

第一步是获取用于条形图基础图的宽格式数据,例如通过使用reshape2::dcasttidyr::spread

library(tidyr)
library(tidyverse)
cleaninput_spread <- cleaninput %>% spread(type, calories) %>% remove_rownames %>% column_to_rownames(var="vendor")
cleaninput_spread

>            club italian roastbeef turkey veggie
> jimmyjohns   NA     640       540    510    690
> subway      310     410       320    280    230

将 NA 值替换为 0:

cleaninput_spread[is.na(cleaninput_spread)] <- 0

底部的堆积条形图:

barplot(as.matrix(cleaninput_spread), main="Calories per Sandwich, by shop",
        xlab="Sandwich", ylab="Calories",
        col=c("darkblue","red"),
        legend = rownames(cleaninput_spread))

【讨论】:

  • 谢谢您,先生,这很有帮助!如果您不介意,我有一个快速跟进:我不时看到这个 %&gt;% 运算符并理解它是一个类似管道的命令;我是否正确阅读了代码,我也可以在单个命令中执行所有这些操作,%&gt;% 主要是为了方便和可读性?再次感谢剧情!
  • 是的,这相当于column_to_rownames(remove_rownames(spread(cleaninput, type, calories)), var="vendor"),并且可以根据需要将每个嵌套函数分配给单独的变量。
【解决方案2】:

这是你要找的吗?

type<-c("italian","turkey","roastbeef","club","veggie","italian","turkey","roastbeef","veggie")
vendor<-c(rep("subway",5),rep("jimmyjohns",4))
calories<-c(410,280,320,310,230,640,510,540,690)
size<-c(rep(6,5),rep(8,4))

cleaninput<-data.frame(type,vendor,calories,size)

#first you calculate the mean by type using by function (base package)  

calor.by.type<-by(cleaninput$calories,INDICES = list(cleaninput$type),FUN = mean)

#then you plot the result from by function

barplot(calor.by.type,main="by function")

【讨论】:

  • 感谢您的帮助!不幸的是,这并不是我真正想要做的——我想按供应商划分每种类型,即 Subway 的“俱乐部”与 jimmyjohns 的“俱乐部”等。我在我的问题中添加了一个预期的输出示例并试图澄清措辞......对不起,如果我不太清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
相关资源
最近更新 更多