Diagtwig de dispersión con barras de error

¿Cómo puedo generar el siguiente gráfico en R? Los puntos que se muestran en la gráfica son los promedios, y sus rangos corresponden a valores mínimos y máximos. Tengo datos en dos archivos (a continuación se muestra un ejemplo).

xy 1 0.8773 1 0.8722 1 0.8816 1 0.8834 1 0.8759 1 0.8890 1 0.8727 2 0.9047 2 0.9062 2 0.8998 2 0.9044 2 0.8960 .. ... 

enter image description here

Antes que nada: es muy desafortunado y sorprendente que R no pueda extraer las barras de error “de fábrica” .

Esta es mi solución favorita, la ventaja es que no necesita ningún paquete adicional . El truco es dibujar flechas (!) Pero con pequeñas barras horizontales en lugar de puntas de flecha (!!!). Esta idea no tan directa proviene de los Consejos de R Wiki y se reproduce aquí como un ejemplo resuelto.

Supongamos que tiene un vector de sdev promedio de valores y otro vector de desviaciones estándar, son de la misma longitud n . Hagamos la abscisa solo el número de estas “medidas”, entonces x <- 1:n . Usando estos, aquí vienen los comandos de trazado:

 plot(x, avg, ylim=range(c(avg-sdev, avg+sdev)), pch=19, xlab="Measurements", ylab="Mean +/- SD", main="Scatter plot with std.dev error bars" ) # hack: we draw arrows but with very special "arrowheads" arrows(x, avg-sdev, x, avg+sdev, length=0.05, angle=90, code=3) 

El resultado es así:

diagrama de dispersión de ejemplo con barras de error std.dev

En las arrows(...) length=0.05 función length=0.05 es el tamaño de la "punta de flecha" en pulgadas, el angle=90 especifica que la "punta de flecha" es perpendicular al eje de la flecha y el parámetro particularmente intuitivo code=3 especifica que queremos dibujar una punta de flecha en ambos extremos de la flecha.

Para las barras de error horizontales son necesarios los siguientes cambios, suponiendo que el vector sdev contiene ahora los errores en los valores x valores y son las ordenadas:

 plot(x, y, xlim=range(c(x-sdev, x+sdev)), pch=19,...) # horizontal error bars arrows(x-sdev, y, x+sdev, y, length=0.05, angle=90, code=3) 

Usando ggplot y un poco de dplyr para la manipulación de datos:

 set.seed(42) df <- data.frame(x = rep(1:10,each=5), y = rnorm(50)) library(ggplot2) library(dplyr) df.summary <- df %>% group_by(x) %>% summarize(ymin = min(y), ymax = max(y), ymean = mean(y)) ggplot(df.summary, aes(x = x, y = ymean)) + geom_point(size = 2) + geom_errorbar(aes(ymin = ymin, ymax = ymax)) 

Si hay una columna de agrupación adicional (el ejemplo de OP ttwig tiene dos barras de error por valor x, diciendo que los datos provienen de dos archivos), entonces debe obtener todos los datos en un dataframe al inicio, agregue la variable de agrupamiento al dplyr::group_by call (p. ej., group_by(x, file) si el file es el nombre de la columna) y agréguelo como estética de “grupo” en ggplot, por ejemplo, aes(x = x, y = ymean, group = file) .

 #some example data set.seed(42) df <- data.frame(x = rep(1:10,each=5), y = rnorm(50)) #calculate mean, min and max for each x-value library(plyr) df2 <- ddply(df,.(x),function(df) c(mean=mean(df$y),min=min(df$y),max=max(df$y))) #plot error bars library(Hmisc) with(df2,errbar(x,mean,max,min)) grid(nx=NA,ny=NULL) 

Para resumir la respuesta de Laryx Decidua:

definir y usar una función como la siguiente

 plot.with.errorbars <- function(x, y, err, ylim=NULL, ...) { if (is.null(ylim)) ylim <- c(min(y-err), max(y+err)) plot(x, y, ylim=ylim, pch=19, ...) arrows(x, y-err, x, y+err, length=0.05, angle=90, code=3) } 

donde uno puede anular el ylim automático, y también pasar parámetros adicionales como main , xlab , ylab .

Otra forma (más fácil, al menos para mí) de hacerlo es a continuación.

 install.packages("ggplot2movies") data(movies, package="ggplot2movies") 

Trazado promedio Longitud vs Clasificación

 rating_by_len = tapply(movies$length, movies$rating, mean) plot(names(rating_by_len), rating_by_len, ylim=c(0, 200) ,xlab = "Rating", ylab = "Length", main="Average Rating by Movie Length", pch=21) 

Agregue barras de error a la gráfica: mean – sd, mean + sd

 sds = tapply(movies$length, movies$rating, sd) upper = rating_by_len + sds lower = rating_by_len - sds segments(x0=as.numeric(names(rating_by_len)), y0=lower, y1=upper) 

Espero que ayude.

Junté el código de inicio a fin de un experimento hipotético con diez mediciones replicadas tres veces. Solo por diversión con la ayuda de otros stackoverflowers. Gracias … Obviamente, los bucles son una opción ya que se puede apply pero me gusta ver qué pasa.

 #Create fake data x <-rep(1:10, each =3) y <- rnorm(30, mean=4,sd=1) #Loop to get standard deviation from data sd.y = NULL for(i in 1:10){ sd.y[i] <- sd(y[(1+(i-1)*3):(3+(i-1)*3)]) } sd.y<-rep(sd.y,each = 3) #Loop to get mean from data mean.y = NULL for(i in 1:10){ mean.y[i] <- mean(y[(1+(i-1)*3):(3+(i-1)*3)]) } mean.y<-rep(mean.y,each = 3) #Put together the data to view it so far data <- cbind(x, y, mean.y, sd.y) #Make an empty matrix to fill with shrunk data data.1 = matrix(data = NA, nrow=10, ncol = 4) colnames(data.1) <- c("X","Y","MEAN","SD") #Loop to put data into shrunk format for(i in 1:10){ data.1[i,] <- data[(1+(i-1)*3),] } #Create atomic vectors for arrows x <- data.1[,1] mean.exp <- data.1[,3] sd.exp <- data.1[,4] #Plot the data plot(x, mean.exp, ylim = range(c(mean.exp-sd.exp,mean.exp+sd.exp))) abline(h = 4) arrows(x, mean.exp-sd.exp, x, mean.exp+sd.exp, length=0.05, angle=90, code=3)