如何在柱状图中为多个变量制作误差棒

3
我希望有人能帮我解决以下问题:
我试图制作一个组合柱状图,显示记录二元变量(性别)的三个连续变量(体温、长度、质量)的均值和标准误差。
我已经成功地绘制出每个变量的均值,但是我似乎无法使用任何我尝试过的代码成功计算这三个变量的标准误差。我尝试了很多方法,但我认为我在这方面走得比较顺利:
    View(test4)
    test4 <- aggregate(test4, 
             by = list(Sex = test4$Sex), 
             FUN = function(x) c(mean = mean(x), sd = sd(x),
                                 n = length(x)))
    test4
    #this produced mean, sd, length for ALL variables (including sex)
    test4<-do.call(test4)
    test4$se<-test4$x.sd / sqrt(test4$x.n)

然后我不断地遇到这个错误:

    Error in sqrt(test4$x.n) : non-numeric argument to mathematical function

我尝试在汇总(test4...)后重新编码以针对我的三个变量,但我无法使它起作用...然后我通过对产生的数据框进行子集操作来排除性别,但没有起作用。然后我尝试将其定义为矩阵或向量,但仍然没有起作用。
我希望我的最终图形的y轴为平均值,x轴为变量(3个子组(Tb、Mass、Length),两个并排的条形图,用于比较男女的值。
如有任何帮助或指导,将不胜感激!
提前致谢! :)

目前这篇文章看起来更像是关于“聚合”而不是绘图的问题。如果你想要绘图,可以尝试使用类似于这个答案的方法进行实验。 - aosmith
2个回答

3

aggregate在尝试输出多列时会给出一些奇怪的输出。如果您希望使用aggregate,我建议将平均值和标准误差作为单独的调用。

然而,这里有一个使用tidyr和dplyr的解决方案,我认为还不错。

我创建了一些数据。希望它看起来像你的数据。在您的问题中包含模拟数据集非常有用。

library(tidyr)
library(dplyr)
library(ggplot2)

# Create some data 
test4 <- data.frame(Sex = rep(c('M', 'F'), 50),
                    bodytemp = rnorm(100),
                    length = rnorm(100), 
                    mass = rnorm(100))

# Gather the data to 'long' format so the bodytemp, length and mass are all in one column
longdata <- gather(test4, variable, value, -Sex)
head(longdata)

# Create the summary statistics seperately for sex and variable (i.e. bodytemp, length and mass)
summary <- longdata %>%
             group_by(Sex, variable) %>%
             summarise(mean = mean(value), se = sd(value) / length(value))

# Plot
ggplot(summary, aes(x = variable, y = mean, fill = Sex)) + 
  geom_bar(stat = 'identity', position = 'dodge') +
  geom_errorbar(aes(ymin = mean - se, ymax = mean + se),                            
                  width = 0.2,
                  position = position_dodge(0.9))

outputbarchart


感谢您的帮助!不幸的是,当我按照这个脚本操作时,并没有生成我想要的图表(可能是因为我们使用了不同的数据集),但它确实让我开始以较长的方式组织我的数据,然后我能够将其与另一个脚本结合起来,该脚本在我只有一个输出时使用。下次我一定会包含一个数据集!再次感谢您的帮助 :) - brittany

0

我的最终图表

更新:我通过将timcdlucas脚本的初始部分与我在绘制单个输出时使用的另一个脚本相结合,成功回答了我的问题。对于其他可能正在寻找类似问题答案的人,我已经发布了我的脚本和生成的图表(请参见上面的链接):

View(test3) #this dataframe was organized as 'sex', 'tb', 'mass', 'svl' 
newtest<-test3
View(newtest)

#transform data to 'long' combining all variables in one column 
longdata<-gather(newtest, variable, value, -Sex)
View(longdata)

#set up table in correct format
longdata2 <- aggregate(longdata$value, 
                 by = list(Sex = longdata$Sex, Variable = longdata$variable),
                 FUN = function(x) c(mean = mean(x), sd = sd(x),
                                     n = length(x)))
longdata2 <- do.call(data.frame, longdata2)
longdata2$se<-longdata2$x.sd / sqrt(longdata2$x.n)
colnames(longdata2)<-c("Sex", "Variable", "mean", "sd", "n", "se")
longdata2$names<-c(paste(longdata2$Variable, "Variable /", longdata2$Sex,    "Sex"))
View(longdata2)
dodge <- position_dodge(width = 0.9)
limits <- aes(ymax = longdata3$mean + longdata3$se,
          ymin = longdata3$mean - longdata3$se)

#To order the bars in the way I desire *might not be necessary for future scripts*
positions<-c("Tb", "SVL", "Mass")

#To plot new table: 

bfinal <- ggplot(data = longdata3, aes(x = factor(Variable), y = mean,
                             fill = factor(Sex)))+
geom_bar(stat = "identity",
         position = position_dodge(0.9))+
geom_errorbar(limits, position = position_dodge(0.9),
            width = (0.25)) +
labs(x = "Variable", y = "Mean") +
ggtitle("")+
scale_fill_discrete(name = "", 
                  labels=c("Male", "Female"))+
scale_x_discrete(breaks=c("Mass", "SVL", "Tb"),
               labels=c("Mass", "SVL", "Tb"), 
               limits=(positions))
bfinal  

:)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接