web-dev-qa-db-fra.com

Comment superposer des tracés de densité dans R?

Je voudrais superposer 2 courbes de densité sur le même appareil avec R. Comment puis-je faire cela? J'ai cherché sur le Web mais je n'ai trouvé aucune solution évidente (je suis plutôt nouveau dans R).

Mon idée serait de lire les données d’un fichier texte (colonnes) puis d’utiliser

plot(density(MyData$Column1))
plot(density(MyData$Column2), add=T)

bien quelque chose dans cet esprit ...

Merci d'avance

73
pasta

utilisez lines pour le second:

plot(density(MyData$Column1))
lines(density(MyData$Column2))

assurez-vous toutefois que les limites de la première parcelle conviennent.

82
cbeleites

ggplot2 est un autre logiciel graphique qui gère des problèmes tels que celui de la plage, que Gavin mentionne d'une manière assez astucieuse. Il gère également la génération automatique de légendes appropriées et a généralement une sensation plus raffinée, à mon avis, avec moins de manipulations manuelles.

library(ggplot2)

#Sample data
dat <- data.frame(dens = c(rnorm(100), rnorm(100, 10, 5))
                   , lines = rep(c("a", "b"), each = 100))
#Plot.
ggplot(dat, aes(x = dens, fill = lines)) + geom_density(alpha = 0.5)

enter image description here

42
Chase

Ajout de la version graphique de base prenant en compte les limites de l’axe des y, ajoutant des couleurs et fonctionnant pour n’importe quel nombre de colonnes:

Si nous avons un ensemble de données:

myData <- data.frame(std.nromal=rnorm(1000, m=0, sd=1),
                     wide.normal=rnorm(1000, m=0, sd=2),
                     exponent=rexp(1000, rate=1),
                     uniform=runif(1000, min=-3, max=3)
                     )

Puis tracer les densités:

dens <- apply(myData, 2, density)

plot(NA, xlim=range(sapply(dens, "[", "x")), ylim=range(sapply(dens, "[", "y")))
mapply(lines, dens, col=1:length(dens))

legend("topright", legend=names(dens), fill=1:length(dens))

Qui donne:

enter image description here

16

Juste pour fournir un ensemble complet, voici une version de la réponse de Chase utilisant lattice:

dat <- data.frame(dens = c(rnorm(100), rnorm(100, 10, 5))
                   , lines = rep(c("a", "b"), each = 100))

densityplot(~dens,data=dat,groups = lines,
            plot.points = FALSE, ref = TRUE, 
            auto.key = list(space = "right"))

qui produit un complot comme celui-ci: enter image description here

12
joran

J'ai pris l'exemple de réseau ci-dessus et fait une fonction astucieuse. Il y a probablement une meilleure façon de faire cela avec remodeler via fusion/moulage. (Commentez ou modifiez si vous voyez une amélioration.)

multi.density.plot=function(data,main=paste(names(data),collapse = ' vs '),...){
  ##combines multiple density plots together when given a list
  df=data.frame();
  for(n in names(data)){
    idf=data.frame(x=data[[n]],label=rep(n,length(data[[n]])))
    df=rbind(df,idf)
  }
  densityplot(~x,data=df,groups = label,plot.points = F, ref = T, auto.key = list(space = "right"),main=main,...)
}

Exemple d'utilisation:

multi.density.plot(list(BN1=bn1$V1,BN2=bn2$V1),main='BN1 vs BN2')

multi.density.plot(list(BN1=bn1$V1,BN2=bn2$V1))
3
Chris

C'est comme ça que je le fais en base (c'est en fait mentionné dans les commentaires de la première réponse mais je montrerai le code complet ici, y compris la légende car je ne peux pas commenter pour le moment ...)

Vous devez d’abord obtenir les informations sur les valeurs maximales de l’axe des y à partir des diagrammes de densité. Il faut donc calculer les densités séparément en premier

dta_A <- density(VarA, na.rm = TRUE)
dta_B <- density(VarB, na.rm = TRUE)

Ensuite, tracez-les en fonction de la première réponse et définissez les valeurs min et max pour l'axe y que vous venez de recevoir. (Je règle la valeur minimale à 0)

plot(dta_A, col = "blue", main = "2 densities on one plot"), 
     ylim = c(0, max(dta_A$y,dta_B$y)))  
lines(dta_B, col = "red")

Ajoutez ensuite une légende dans le coin supérieur droit

legend("topright", c("VarA","VarB"), lty = c(1,1), col = c("blue","red"))
3
R. Prost

Lorsqu'il existe des problèmes de limites d'axes incompatibles, le bon outil dans base graphics est d'utiliser matplot. La clé consiste à utiliser les arguments from et to pour density.default. C'est un peu rusé, mais assez simple de se lancer:

set.seed(102349)
x1 = rnorm(1000, mean = 5, sd = 3)
x2 = rnorm(5000, mean = 2, sd = 8)

xrng = range(x1, x2)

#force the x values at which density is
#  evaluated to be the same between 'density'
#  calls by specifying 'from' and 'to'
#  (and possibly 'n', if you'd like)
kde1 = density(x1, from = xrng[1L], to = xrng[2L])
kde2 = density(x2, from = xrng[1L], to = xrng[2L])

matplot(kde1$x, cbind(kde1$y, kde2$y))

enter image description here

Ajoutez des options comme vous le souhaitez (matplot accepte tous les arguments standard plot/par, par exemple lty, type, col, lwd, ...).

2
MichaelChirico