2015-09-02 2 views
2

пользователей Уважаемые StackOverflow,Ошибка при добавлении errorbars к ggplot

Я хотел бы обратить сгруппированный barplot с тремя независимыми переменными с ошибками. Я основывал свой график на примере Stacked Overflow (сложенные столбцы в сгруппированных барах), используя ggplot с geom_bar. Когда я добавляю geom_errorbar в соответствии с примерами страниц помощи, я получаю следующее сообщение об ошибке: Error in if (empty(data)) { : missing value where TRUE/FALSE needed

Это сценарий, я использую:

treatment<-rep(c(rep(c(1),8),rep(c(2),8)),2) 
origin<-rep(c("A","B"),16) 
time<-c(rep(c(5),16),rep(c(10),16)) 
sulfide<-c(0,10,5,8,9,6,16,18,20,25,50,46,17,58,39,43,20,25,50,46,17,58,39,43,100,120,103,104,150,160,200,180) 

Reed<-data.frame(treatment,origin,time,sulfide) 

# specify factor types 
Reed$treatment<-as.factor(Reed$treatment) 
Reed$origin<-as.character(Reed$origin) 
Reed$time<-as.factor(Reed$time) 

library(ggplot2) 
library(scales) 

#draw plot 
ggplot() +geom_bar(data=Reed, aes(y = sulfide, x = treatment, fill=origin), stat="identity",position="dodge") +theme_bw() + facet_grid(~ time)+xlab("treatment") +ylab("Sulfide")+ggtitle("Time)") 

Это, как я добавил баров ошибки:

ErrorBars <- function(x, y, upper, lower=upper, length=0.03,...{if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper))stop("vectors must be same length")arrows(x,y+upper, x, y-lower, angle=90, code=3, length=length, ...)}#function for errorbars 

SE<- function(x) sqrt(var(x,na.rm=TRUE)/length(na.omit(x))) #function for SE 

Reed$trt<- paste(Reed$treatment,Reed$origin,sep="")#combine treatment and origin to a column 
mean_Reed<-data.frame(tapply(Reed$sulfide,list(Reed$trt,Reed$time),mean,na.rm=TRUE)) #mean 
SE_Reed<-data.frame(tapply(Reed$sulfide,list(Reed$trt, Reed$time),SE)) # SE 

limits <- aes(ymax = mean_Reed + SE_Reed, ymin=mean_Reed - SE_Reed)# Define the top and bottom of the errorbars 

#plot with error bars: 
ggplot() +geom_bar(data=Reed, aes(y = sulfide, x = treatment, fill=origin), stat="identity",position="dodge") +theme_bw() + facet_grid(~ time)+xlab("treatment") +ylab("Sulfide")+ggtitle("Time)"+ geom_errorbar(limits, width=.2,position="dodge") 

Я действительно не могу найти то, что я делаю неправильно. Надеюсь, вы можете мне помочь :)

ответ

2

Оставляя в стороне вопрос о барах ошибок на данный момент, существует гораздо более серьезная проблема с вашим сюжетом. У вас есть 2 значения по каждому из treatment, time и origin, всего 8 комбинаций, но 32 значения сульфида - поэтому для каждой комбинации имеется 4 значения сульфида. При печати с использованием этого, например,

ggplot(data=Reed) + 
    geom_bar(aes(y = sulfide, x = treatment, fill=origin), stat="identity",position="dodge") + 
    facet_grid(~ time)+xlab("treatment") +ylab("Sulfide") 

вы черчение брусков для всех четырех значения сульфидного друг на друг все в том же цвете. Это приводит к отображению только максимального значения. Немного трудно поверить, что это то, что вы намеревались, и даже если вы сделали, есть лучший способ сделать это. Например, если вы хотите построить среднее значение sulfide для каждой комбинации факторов, вы можете сделать это таким образом.

ggp <- ggplot(data=Reed, aes(y = sulfide, x = as.factor(treatment), group=origin)) + 
    geom_bar(aes(fill=origin), stat="summary", fun.y=mean, position="dodge") + 
    theme_bw() + 
    facet_grid(~ time)+xlab("treatment") +ylab("Sulfide")+ggtitle("Time") 
ggp 

При этом используется stat="summary" автоматически суммировать результат с помощью функции агрегирующего mean (fun.y=mean).

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

se <- function(y) sd(y)/length(y) # to calculate standard error in the mean 
ggp+stat_summary(geom="errorbar",position=position_dodge(width=0.85), 
       fun.data=function(y)c(ymin=mean(y)-se(y),ymax=mean(y)+se(y)), width=0.1) 

Обратите внимание, что нет необходимости объединять данные извне - ggplot делает это для вас.

Наконец, этот подход позволяет использовать множество встроенных функций для создания доверительных пределов с большей статистической строгостью.

ggp+stat_summary(fun.data=mean_cl_normal, conf.int=0.95, 
       geom="errorbar",position=position_dodge(width=0.85), width=0.1) 

Так здесь мы используем встроенную функцию mean_cl_normalggplot для расчета 95% доверительного интервала на среднем предполагающей данных следует нормальному распределению (и, следовательно, средства будут следовать т-распределение). Мы используем аргумент conf.int=..., чтобы указать желаемый доверительный интервал, но по умолчанию 0,95, поэтому в этом примере это действительно не нужно.

Существует несколько других функций этого типа: см. the documentation и ссылки в нем для пояснения.

1

Если вы хотите построить свои бары ошибок, создав сводный набор данных, вам просто нужно получить этот набор данных в правильном формате. Для этого есть много вариантов; Я буду использовать dplyr. Обратите внимание: я сохраняю все переменные группировки из графика в этом наборе данных в «аккуратном» формате, причем каждая переменная в отдельном столбце.

library(dplyr) 
meandat = Reed %>% 
    group_by(treatment, time, origin) %>% 
    summarise(mean = mean(sulfide, na.rm = TRUE), se = SE(sulfide)) 

Source: local data frame [8 x 5] 
Groups: treatment, time [?] 

    treatment time origin mean  se 
    (fctr) (fctr) (chr) (dbl)  (dbl) 
1   1  5  A 7.50 3.378856 
2   1  5  B 10.50 2.629956 
3   1  10  A 31.50 7.858117 
4   1  10  B 43.00 6.819091 
5   2  5  A 31.50 7.858117 
6   2  5  B 43.00 6.819091 
7   2  10  A 138.25 23.552689 
8   2  10  B 141.00 17.540429 

Теперь бары ошибок можно добавить через geom_errorbar. Вы увидите, что я установил эстетику по всему миру в пределах ggplot, чтобы сохранить себя, чтобы повторно ввести некоторые из них, но вы можете изменить это, как хотите. Я использую position_dodge, чтобы получить правильные бары ошибок над каждым баром.

ggplot(data = Reed, aes(y = sulfide, x = treatment, fill=origin)) + 
    geom_bar(stat="identity", position="dodge") + 
    theme_bw() + 
    facet_grid(~ time)+ 
    xlab("treatment") + 
    ylab("Sulfide")+ 
    ggtitle("Time")+ 
    geom_errorbar(data = meandat, aes(ymin = mean - se, ymax = mean + se, y = mean), 
       position = position_dodge(width = .9)) 

enter image description here

Вы на самом деле можете сделать все это с помощью stat_summary, а не расчета сводных статистических данных «вручную». Пример: here. Код будет выглядеть так, и дает тот же сюжет, что и выше.

ggplot(data = Reed, aes(y = sulfide, x = treatment, fill=origin)) + 
    geom_bar(stat="identity",position="dodge") + 
    theme_bw() + 
    facet_grid(~ time) + 
    xlab("treatment") + 
    ylab("Sulfide") + 
    ggtitle("Time") + 
    stat_summary(geom = "errorbar", fun.data = mean_cl_normal, mult = 1, 
       position = position_dodge(width = .9)) 

Я использую версию развития ggplot2, ggplot2_1.0.1.9003, и обнаружил, что мне нужно, чтобы добавить stat_summary аргументы функции через fun.args. Это выглядело бы как fun.args = list(mult = 1), чтобы получить бары ошибок с 1 стандартной ошибкой.

+0

Большое спасибо, вы оба! @jlhoward – MAK

Смежные вопросы