2013-04-26 16 views
12

Sto provando a calcolare i valori minimi di una colonna numerica per ciascun livello di un fattore, mantenendo i valori di un altro fattore nel frame di dati risultante.Aggregato per livelli di fattore, mantenendo altre variabili nel riquadro dati risultante

# dummy data 
dat <- data.frame(
    code = c("HH11", "HH45", "JL03", "JL03", "JL03", "HH11"), 
    index = c("023434", "3377477", "3388595", "3377477", "1177777", "023434"), 
    value = c(24.1, 37.2, 78.9, 45.9, 20.0, 34.6) 
    ) 

Il risultato che voglio è il minimo di value per ciascun livello di code, mantenendo index nella cornice dati risultanti.

# result I want: 
# code value index 
# 1 HH11 24.1 023434 
# 2 HH45 37.2 3377477 
# 3 JL03 20.0 1177777 


# ddply attempt 
library(plyr) 
ddply(dat, ~ code, summarise, val = min(value)) 
# code val 
# 1 HH11 24.1 
# 2 HH45 37.2 
# 3 JL03 20.0 


# base R attempt 
aggregate(value ~ code, dat, min) 
# code value 
# 1 HH11 24.1 
# 2 HH45 37.2 
# 3 JL03 20.0 

risposta

12

è necessario utilizzare merge sul risultato di aggregate e originale data.frame

merge(aggregate(value ~ code, dat, min), dat, by = c("code", "value")) 
## code value index 
## 1 HH11 24.1 023434 
## 2 HH45 37.2 3377477 
## 3 JL03 20.0 1177777 
+0

mi ha battuto per secondi! – Chris

0

Beh, qualche minuto più cercando mi avrebbe finita lì ... this answer sembra fare il trucco:

unione (dat, aggregato (valore ~ ​​codice, dat, min))

3

Solo per dimostrare che c'è sempre più modi per scuoiare un gatto:

Utilizzando ave per ottenere gli indici delle righe minimi in ogni gruppo:

dat[which(ave(dat$value,dat$code,FUN=function(x) x==min(x))==1),] 

# code index value 
#1 HH11 023434 24.1 
#2 HH45 3377477 37.2 
#5 JL03 1177777 20.0 

Questo metodo ha anche il potenziale beneficio di restituire più righe per code gruppo nel caso di più i valori sono il minimo

E un altro metodo che utilizza by:

do.call(rbind, 
    by(dat, dat$code, function(x) cbind(x[1,c("code","index")],value=min(x$value))) 
) 
#  code index value 
# HH11 HH11 023434 24.1 
# HH45 HH45 3377477 37.2 
# JL03 JL03 3388595 20.0 
0

Se aveva aggiunto nella variabile indice che avrebbe fatto.

library(plyr) 

# ddply 
ddply(dat, .(code,index), summarise, val = min(value)) 

# base R 
aggregate(value ~ code + index, dat, min) 
1

Con i pacchetti dplyr e data.table, è possibile effettuare le seguenti operazioni. È possibile ottenere un indice per la riga con il valore minimo per ciascun gruppo. È possibile utilizzarlo in slice() se si utilizza dplyr. È possibile ottenere lo stesso sottotitolo utilizzando .SD se si utilizza data.table.

library(dplyr) 
library(data.table) 

dat %>% 
group_by(code) %>% 
slice(which.min(value)) 

# code index value 
# <fctr> <fctr> <dbl> 
#1 HH11 023434 24.1 
#2 HH45 3377477 37.2 
#3 JL03 1177777 20.0 

setDT(dat)[, .SD[which.min(value)], by = code] 

# code index value 
#1: HH11 023434 24.1 
#2: HH45 3377477 37.2 
#3: JL03 1177777 20.0 
Problemi correlati