web-dev-qa-db-fra.com

Ajouter des barres d'erreur pour afficher l'écart type sur un tracé en R

Pour chaque valeur X-, j'ai calculé la valeur moyenne Y- et l'écart type (sd) de chaque valeur Y

x  = 1:5
y  = c(1.1, 1.5, 2.9, 3.8, 5.2)
sd = c(0.1, 0.3, 0.2, 0.2, 0.4)

plot (x, y)

Comment utiliser l'écart type pour ajouter des barres d'erreur à chaque point de donnée de mon tracé?

30
John Garreth

Un problème avec la solution csgillespie apparaît lorsque vous avez un axe X logarithmique. Vous aurez une longueur différente des petites barres à droite et à gauche (epsilon suit les valeurs x).

Vous devriez mieux utiliser la fonction errbar du paquetage Hmisc:

d = data.frame(
  x  = c(1:5)
  , y  = c(1.1, 1.5, 2.9, 3.8, 5.2)
  , sd = c(0.2, 0.3, 0.2, 0.0, 0.4)
)

##install.packages("Hmisc", dependencies=T)
library("Hmisc")

# add error bars (without adjusting yrange)
plot(d$x, d$y, type="n")
with (
  data = d
  , expr = errbar(x, y, y+sd, y-sd, add=T, pch=1, cap=.1)
)

# new plot (adjusts Yrange automatically)
with (
  data = d
  , expr = errbar(x, y, y+sd, y-sd, add=F, pch=1, cap=.015, log="x")
)
18
R_User

Une solution avec ggplot2:

qplot(x,y)+geom_errorbar(aes(x=x, ymin=y-sd, ymax=y+sd), width=0.25)

enter image description here

29
juba

En plus de la réponse de @ csgillespie, segments est également vectorisé pour aider avec ce genre de chose:

plot (x, y, ylim=c(0,6))
segments(x,y-sd,x,y+sd)
epsilon <- 0.02
segments(x-epsilon,y-sd,x+epsilon,y-sd)
segments(x-epsilon,y+sd,x+epsilon,y+sd)

enter image description here

22
thelatemail

Vous pouvez utiliser arrows:

arrows(x,y-sd,x,y+sd, code=3, length=0.02, angle = 90)
21
SmartCH

Vous pouvez utiliser segments pour ajouter les barres dans les graphiques de base. Ici, epsilon contrôle la ligne en haut et en bas de la ligne.

plot (x, y, ylim=c(0, 6))
epsilon = 0.02
for(i in 1:5) {
    up = y[i] + sd[i]
    low = y[i] - sd[i]
    segments(x[i],low , x[i], up)
    segments(x[i]-epsilon, up , x[i]+epsilon, up)
    segments(x[i]-epsilon, low , x[i]+epsilon, low)
}

Comme @thelatemail le souligne, j'aurais vraiment dû utiliser des appels de fonction vectorisés:

segments(x, y-sd,x, y+sd)
epsilon = 0.02
segments(x-epsilon,y-sd,x+epsilon,y-sd)
segments(x-epsilon,y+sd,x+epsilon,y+sd)

enter image description here

20
csgillespie