3

我希望有人可以帮助我解决以下问题:

我正在尝试制作一个组合条形图,显示为二进制变量(性别)记录的 3 个不同连续变量(体温、长度、质量)的平均值和标准误差。

我已经能够绘制每个变量的平均值,但我似乎无法使用我尝试过的任何代码成功计算这 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...)之后重新编码以定位我的 3 个变量,但我无法让它工作......然后我通过生成的数据框进行子集化以排除性别,但这没有用。然后我尝试将其定义为矩阵或向量,但仍然不起作用。

我希望我的最终图表有 y 轴 = 平均值,x 轴 = 变量(3 个子组(Tb、质量、长度),两个条并排显示男性和女性值以进行比较。

任何人都可以提供的任何帮助或指导将不胜感激!!

提前谢谢了!:)

4

2 回答 2

3

aggregate当您尝试输出多于一列时,确实会给出一些疯狂的输出。如果你想使用aggregate我的意思是和 SE 作为单独的调用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))

输出条形图

于 2016-05-10T16:11:47.253 回答
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  

:)

于 2016-05-11T04:29:21.573 回答