2011-05-05 4 views
10

Je remarque un comportement incohérent lors de l'application de la fonction median() aux données. "Comportement incohérent" signifie généralement que je ne comprends pas quelque chose, alors j'espère que quelqu'un sera prêt à éclaircir cela pour moi.Comportement impair avec median()?

I se rendre compte que certaines fonctions (par exemple, min(), max()) convertissent la trame de données dans un vecteur et retourner la valeur correspondante de l'ensemble tandis que df mean() et sd() renvoient une valeur pour chaque colonne. Bien qu'un peu confus, ces différences de comportement ne causent pas beaucoup de problèmes puisque la plupart du code se casserait si un scalaire est renvoyé à la place d'un vecteur. Cependant, median() semble être incohérent. Par exemple:

dat <- data.frame(x=1:100, y=2:101) 
median(dat) 

Renvoie un vecteur: [1] 50.5 51.5

Mais, parfois, il se brise:

dat2 <- data.frame(x=1:100, y=rnorm(100)) 
median(dat2) 

Retours: [1] NA NA Warning messages: 1: In mean.default(X[[1L]], ...) : argument is not numeric or logical: returning NA 2: In mean.default(X[[2L]], ...) : argument is not numeric or logical: returning NA

Cependant, median(dat2$x) et median(dat2$y) à la fois donner le résultat correct.

Voir également les éléments suivants:

dat3 <- data.frame(x=1:100, y=1:100) 
dat4 <- data.frame(x=1:100, y=100:199) 

Dans ce qui précède, median(dat3) retours [1] 50.5 NA tandis que median(dat4) retours [1] 50.5 149.5! Je m'attendrais à ce que les deux ou aucun d'entre eux fonctionnent. Donc, je ne comprends pas à quel point la fonction median() fonctionne.

En outre, des fonctions telles que sd, mean(), min() et max() tous donnent leurs attendus (si apparemment incompatibles) des résultats dans tous les cas ci-dessus. Je sais que je peux utiliser quelque chose comme sapply(dat2, median) pour obtenir le résultat nécessaire, mais je me demande pourquoi les dieux R ont choisi d'implémenter ces fonctions de statistiques de base d'une manière qui, au moins en surface, semble incohérente. Je soupçonne que moi, et probablement d'autres néophytes, ne comprenons probablement pas un concept fondamental, et j'apprécierais votre perspicacité.

+1

J'aurais aimé lire R Inferno de plus près. Je suis juste retourné et regardé, et l'auteur déclare: «L'exemple de la médiane avec les bases de données est un problème ... il n'y a pas une méthode de base de données de la médiane, dans ce cas particulier, il obtient la bonne réponse, mais c'est Dans d'autres cas, vous obtenez des réponses bizarres. " (p.54). Je suis maintenant motivé pour donner à R Inferno une bonne lecture solide ce week-end. –

Répondre

12

Ce phénomène exact a été récemment discuté dans le thread median and data frames sur R-devel. Le consensus semblait être que la méthode mean.data.frame devrait être dépréciée et les utilisateurs devraient compter sur sapply.

+1

+1 pour souligner le problème 'mean.data.frame'. – aL3xa

+2

Parfait, merci! Je suis un peu gêné de ne pas avoir trouvé ce fil. Il est clair que 'mean' et' sd' sont les fonctions inconsistantes, pas 'median' (bien que je pense encore que ce soit incohérent à d'autres égards). En rétrospective, il est étrange de s'attendre à ce qu'une fonction qui agrège habituellement un vecteur de nombres travaille sur une trame de données. Une meilleure question aurait demandé pourquoi mean.data.frame a été mis en œuvre en premier lieu. –

5

median n'a pas de metod pour les objets de classe data.frame, contrairement à mean. Utilisez le package plyr et la fonction colwise pour obtenir le résultat souhaité. Ou utilisez la famille de fonctions *apply.

> sapply(mtcars, median)                          
    mpg  cyl disp  hp drat  wt qsec  vs  am gear            
19.200 6.000 196.300 123.000 3.695 3.325 17.710 0.000 0.000 4.000            
    carb                              
    2.000                              
> colwise(median)(mtcars)                          
    mpg cyl disp hp drat wt qsec vs am gear carb                  
1 19.2 6 196.3 123 3.695 3.325 17.71 0 0 4 2 
+0

Merci aL3xa. Il a été mon habitude d'utiliser sapply. Je suis encore un peu nouveau à R et je suis encore parfois perturbé par le fait que les fonctions ne spécifient pas les types d'argument et lancent une erreur si quelque chose d'inapproprié leur est passé. Il semble que la meilleure habitude est de toujours utiliser saphly ou colwise quand un résultat colonne par colonne est désiré. –

+0

Vous devriez utiliser les familles '* apply', c'est une bonne pratique. – aL3xa

1

La meilleure façon est le paquet miscTools

> library(miscTools) 
> dat3 <- data.frame(x=-50:50, y=(-50:50)^2) 
> colMedians(dat3) 
    x y 
    0 625 

qui est correct, contrairement à

> median(dat3) 
[1] 0 850 

Le paquet matrixStats a également une fonction colMedians, mais pas pour dataframes.

+0

Merci @Henry. Je ne savais pas à propos de miscTools; On dirait qu'il y a quelques bons outils d'algèbre linéaire. –

Questions connexes