Selecione um valor com base em um valor mais alto em outra coluna
Pergunta
Eu não entendo por que eu não consigo encontrar uma solução para isso, pois sinto que é uma bela questão básica.Precisa pedir ajuda, então.Eu quero reorganizar airquality conjunto de dados por mês, com o máximo de temp valor para cada mês.Além disso, eu quero encontrar o dia correspondente para cada mensais de temperatura máxima.O que é o mais preguiçoso (código-wise) maneira de fazer isso?
Eu tentei seguir sem sucesso:
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)
Eu sou algo como isto:
month day temp
5 7 89
...
Solução
Há uma discussão sobre um tempo atrás sobre se ser preguiçoso é bom ou não.Anwyay, este é curto e natural para escrever e ler (e é rápido de dados de grandes dimensões, assim você não precisa mudar ou otimizá-lo mais tarde) :
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
é o subconjunto dos dados de cada grupo, e você apenas deseja que a linha dele com o maior Temp, iiuc.Se você precisar de número de linha, em seguida, que pode ser adicionado.
Ou para obter todas as linhas onde o max está vinculado :
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
Outras dicas
Outra abordagem com 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)
Dá
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, ainda mais simples
require(reshape2)
require(plyr)
names(airquality) <- tolower(names(airquality))
ddply(airquality, .(month), subset,
subset = temp == max(temp), select = c(month, day, temp) )
como cerca de 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)
Como você pode ver, a temperatura máxima do mês acontece em mais de um dia.Se você deseja um comportamento diferente, a função é fácil de ajustar.
Ou se você quiser usar o data.table
pacote (por exemplo, se a velocidade é um problema e o conjunto de dados é grande ou se você preferir a sintaxe):
library(data.table)
DT <- data.table(airquality)
DT[, list(maxTemp=max(Temp), dayMaxTemp=.SD[max(Temp)==Temp, Day]), by="Month"]
Se você quer saber o que o .SD
significa, dê uma olhada aqui: ENTÃO,