Шановні користувачі Stackoverflow
Я хотів би намалювати згрупований барель з трьоманезалежні змінні з помилками. Я заснував графік на прикладі "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 для відповіді № 1Залишивши помилку помилок на даний момент, існує набагато серйозніша проблема з вашим сюжетом. У вас є 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)
Отже, ми використовуємо ggplot
вбудована функція mean_cl_normal
для розрахунку 95% довірчих меж для середнього, припускаючи, що дані слідують за нормальним розподілом (а це, отже, означатиметься за t-розподілом). Ми використовуємо аргумент conf.int=...
щоб вказати бажаний довірчий інтервал, але за умовчанням це 0,95, так що це дійсно не було потрібно в цьому прикладі.
Є ще кілька функцій такого типу: див документація і посилання на них для пояснення.
2 для відповіді № 2
Якщо ви хочете створити панелі помилок, створивши сукупний набір даних, потрібно просто отримати цей набір даних у правильному форматі. Для цього є багато варіантів; Я буду використовувати 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))
Ви дійсно можете зробити все це через stat_summary
, а не обчислення підсумкової статистики "вручну". Прикладом є тут. Код буде виглядати так, і дає той самий сюжет, як описано вище.
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 стандартної помилки.