2012-05-22 5 views
6

Je ne comprends pas pourquoi je ne trouve pas de solution pour cela, car je pense que c'est une question assez simple. Besoin de demander de l'aide, alors. Je souhaite réorganiser le jeu de données de qualité d'air par mois avec la valeur de température maximale pour chaque mois. En outre, je veux trouver le jour correspondant pour chaque température maximale mensuelle. Quel est le moyen le plus paresseux (code-sage) de faire cela?Sélectionnez une valeur basée sur la valeur la plus élevée dans une autre colonne.

J'ai essayé sans succès suivais:

require(reshape2) 
names(airquality) <- tolower(names(airquality)) 
mm <- melt(airquality, id.vars = c("month", "day"), meas = c("temp")) 

dcast(mm, month + day ~ variable, max) 
aggregate(formula = temp ~ month + day, data = airquality, FUN = max) 

Je suis après quelque chose comme ceci:

month day temp 
5  7 89 
... 

Répondre

5

Il y a longtemps que l'on se demandait si être paresseux était bon ou pas. Anwyay, c'est court et naturel d'écrire et de lire (et est rapide pour les grandes données de sorte que vous n'avez pas besoin de changer ou d'optimiser ultérieurement):

require(data.table) 
DT=as.data.table(airquality) 

DT[,.SD[which.max(Temp)],by=Month] 

    Month Ozone Solar.R Wind Temp Day 
[1,]  5 45  252 14.9 81 29 
[2,]  6 NA  259 10.9 93 11 
[3,]  7 97  267 6.3 92 8 
[4,]  8 76  203 9.7 97 28 
[5,]  9 73  183 2.8 93 3 

.SD est le sous-ensemble des données pour chaque groupe, et vous voulez juste la rangée avec le plus grand Temp, iiuc. Si vous avez besoin du numéro de ligne, cela peut être ajouté.

Ou pour obtenir toutes les lignes où le max est lié:

DT[,.SD[Temp==max(Temp)],by=Month] 

    Month Ozone Solar.R Wind Temp Day 
[1,]  5 45  252 14.9 81 29 
[2,]  6 NA  259 10.9 93 11 
[3,]  7 97  267 6.3 92 8 
[4,]  7 97  272 5.7 92 9 
[5,]  8 76  203 9.7 97 28 
[6,]  9 73  183 2.8 93 3 
[7,]  9 91  189 4.6 93 4 
+0

Merci les gars! Je n'ai pas utilisé le package data.table précédemment, il s'agit donc d'une fois. "Réponse acceptée" car celle-ci était la plus complète (et légèrement plus courte que Chritoph_J's). Vous l'auriez tous mérité (+1 pour tout le monde). – Mikko

+0

Je me demande s'il existe une solution plus concise dans n'importe quelle langue. Je ne devine pas. –

2

Que diriez-vous avec plyr? Comme vous pouvez le voir, la température maximale pour le mois arrive sur plus d'un jour. Si vous voulez un comportement différent, la fonction est assez facile à régler.

2

Ou si vous voulez utiliser le package data.table (par exemple, si la vitesse est un problème et l'ensemble de données est grande ou si vous préférez la syntaxe):

library(data.table) 
DT <- data.table(airquality) 
DT[, list(maxTemp=max(Temp), dayMaxTemp=.SD[max(Temp)==Temp, Day]), by="Month"] 

Si vous voulez savoir ce que le .SD est synonyme de, regardez ici: SO

+0

Je pense que vous me battez sur celui-ci :) –

+0

Dans le temps, oui, par deux secondes (le temps de célébrer ;-) Mais votre tour «which.max» est soigné ... donc +1 pour ça! –

3

Une autre approche avec plyr

require(reshape2) 
names(airquality) <- tolower(names(airquality)) 
mm <- melt(airquality, id.vars = c("month", "day"), meas = c("temp"), value.name = 'temp') 

library(plyr) 

ddply(mm, .(month), subset, subset = temp == max(temp), select = -variable) 

Donne

month day temp 
1  5 29 81 
2  6 11 93 
3  7 8 92 
4  7 9 92 
5  8 28 97 
6  9 3 93 
7  9 4 93 

Ou, encore plus simple

require(reshape2) 
require(plyr) 
names(airquality) <- tolower(names(airquality)) 
ddply(airquality, .(month), subset, 
    subset = temp == max(temp), select = c(month, day, temp)) 
Questions connexes