Selezionare un valore per in base a un valore più alto in un'altra colonna

StackOverflow https://stackoverflow.com//questions/10705290

  •  13-12-2019
  •  | 
  •  

Domanda

Non capisco perché non riesco a trovare una soluzione per questo, dal momento che sento che questa è una domanda piuttosto base.Hai bisogno di chiedere aiuto, allora.Voglio riorganizzare il set di dati di Airquality per mese con il massimo valore temp per ogni mese.Inoltre voglio trovare il giorno corrispondente per ogni temperatura massima mensile.Qual è il modo più leggero (codice-saggio) per farlo?

Ho provato a seguire senza successo:

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

Sono dopo qualcosa del genere:

month day temp
5     7    89
...
.

È stato utile?

Soluzione

C'era una discussione un po 'indietro sul fatto che sia pigro sia buono o meno.ANWYAY, questo è breve e naturale da scrivere e leggere (ed è veloce per i dati di grandi dimensioni, quindi non è necessario modificarlo o ottimizzarlo in seguito):

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 è il sottoinsieme dei dati per ciascun gruppo e vuoi solo la riga da esso con il più grande temperatura, Iiuc.Se è necessario il numero di riga, è possibile aggiungere.

o per ottenere tutte le righe in cui il Max è legato:

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
.

Altri suggerimenti

Un altro approccio con 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)
.

  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
.

o, anche più semplice

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

Che ne dici di plyr?

max.func <- function(df) {
   max.temp <- max(df$temp)

   return(data.frame(day = df$Day[df$Temp==max.temp],
                     temp = max.temp))
}

ddply(airquality, .(Month), max.func)
.

Come puoi vedere, la temperatura massima per il mese avviene su più di un giorno.Se si desidera un comportamento diverso, la funzione è abbastanza facile da regolare.

o se si desidera utilizzare il pacchetto data.table (ad esempio, se la velocità è un problema e il set di dati è grande o se si preferisce la sintassi):

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

Se vuoi sapere cosa significa il .SD, dai un'occhiata qui: Allora

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top