Как сделать планки погрешностей для нескольких переменных в барном чате

Я надеялся, что кто-то может помочь мне со следующей проблемой:

Я пытаюсь сделать комбинированную гистограмму, показывающую средние и стандартные ошибки для 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, масса, длина) с двумя столбцами рядом, показывающими мужские и женские значения для сравнения.

Любая помощь или направление, которое кто-либо мог бы предоставить, были бы очень признательны!

Спасибо заранее! :)


person brittany    schedule 10.05.2016    source источник
comment
В настоящее время это звучит как вопрос о aggregate, а не вопрос о графике. Для построения графика вы можете попробовать поиграть с чем-то вроде этого ответа.   -  person aosmith    schedule 10.05.2016


Ответы (2)


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))

outputbarchart

person timcdlucas    schedule 10.05.2016
comment
Спасибо за вашу помощь! К сожалению, когда я следовал этому сценарию, он не создавал график, который я хотел (вероятно, потому, что мы работали с разными наборами данных), но это помогло мне начать с долгой организации моих данных, а затем я смог присоединиться к ним с помощью другой сценарий, который я использовал, когда у меня был только один вывод. Я обязательно включу набор данных в следующий раз! Еще раз спасибо за помощь :) - person brittany; 11.05.2016

Мой последний сюжет

Обновление: я смог ответить на свой вопрос, объединив начальную часть сценария 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  

:)

person brittany    schedule 11.05.2016