我希望有人可以帮我解决以下问题:
我试图制作一个组合条形图,显示为二元变量(性别)记录的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
我尝试重新编码以在聚合后测试我的3个变量(test4 ...)但是我无法使其工作......然后我通过结果数据框子集来排除性别,但这不起作用。然后我尝试将其定义为矩阵或向量,但仍然无效。
我希望我的最终图表有y轴=平均值,x轴=可变(3个子组(Tb,质量,长度),两个条并排显示男性和女性值进行比较。
任何人可以提供的任何帮助或指示都将非常感谢!!
非常感谢提前! :)
答案 0 :(得分:0)
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))
答案 1 :(得分: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
:)