Gráfico de dispersão com barras de erro

Como posso gerar o seguinte gráfico em R? Os pontos, mostrados no gráfico, são as médias e seus intervalos correspondem aos valores mínimo e máximo. Eu tenho dados em dois arquivos (abaixo está um exemplo).

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

insira a descrição da imagem aqui

Primeiro de tudo: é muito lamentável e surpreendente que R não possa desenhar barras de erro “fora da checkbox” .

Aqui está a minha solução favorita, a vantagem é que você não precisa de nenhum pacote extra . O truque é desenhar setas (!), Mas com pequenas barras horizontais em vez de pontas de seta (!!!). Essa idéia não tão direta vem das R Wiki Tips e é reproduzida aqui como um exemplo elaborado.

Vamos supor que você tenha um vetor de “valores médios” avg e outro vetor de “desvios padrão” sdev , eles são do mesmo comprimento n . Vamos fazer a abscissa apenas o número dessas “medidas”, então x <- 1:n . Usando estes, aqui vêm os comandos de plotagem:

 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) 

O resultado é assim:

exemplo de gráfico de dispersão com barras de erro std.dev

Nas arrows(...) length=0.05 function length=0.05 é o tamanho da "ponta da seta" em polegadas, angle=90 especifica que a "ponta da seta" é perpendicular ao eixo da seta, e o code=3 particularmente intuitivo code=3 parâmetro especifica queremos desenhar uma ponta de seta nas duas extremidades da seta.

Para barras de erro horizontais, as seguintes mudanças são necessárias, assumindo que o vetor sdev agora contém os erros nos valores x valores y são as 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 e um pouco dplyr para manipulação de dados:

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

Se houver uma coluna de agrupamento adicional (a plotagem de exemplo do OP tiver duas barras de erro por valor x, dizendo que os dados são provenientes de dois arquivos), você deve obter todos os dados em um quadro de dados no início, adicionar a variável de agrupamento ao dplyr::group_by call (por exemplo, group_by(x, file) se file é o nome da coluna) e adicione-o como uma estética “group” no ggplot, por exemplo, 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 a resposta de Laryx Decidua:

definir e usar uma function como a seguinte

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

onde se pode sobrescrever o ylim automático e também passar parâmetros extras como main , xlab , ylab .

Outra maneira (mais fácil – pelo menos para mim) de fazer isso está abaixo.

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

Tamanho médio do lote vs sorting

 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) 

Adicionar barras de erro ao gráfico: média – sd, média + 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 ajude.

Eu juntei o começo ao fim do código de um experimento hipotético com dez medidas replicadas três vezes. Apenas por diversão com a ajuda de outras stackoverflowers. Obrigado … Obviamente, os loops são uma opção, pois o apply pode ser usado, mas eu gosto de ver o que acontece.

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