2013-04-26 9 views
12

Próbuję obliczyć minimalne wartości kolumny numerycznej dla każdego poziomu czynnika, zachowując wartości innego współczynnika w wynikowej ramce danych.Agregacja według poziomów czynników, zachowując inne zmienne w wynikowej ramce danych

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

Wynik że zubożenie minimum value dla każdego poziomu code utrzymując index w otrzymanej ramki danych.

# 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 

Odpowiedz

12

Trzeba użyć merge na skutek aggregate i oryginalny 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

bij mnie o sekundę! – Chris

0

Dobrze, kilka minut Wyszukiwanie by zdobyć mnie tam ... this answer wydaje rade:

Połączenie (dat, agregacja (wartość ~ kod, dat, min))

3

Tylko po to, aby pokazać, że zawsze jest wiele sposobów na skórę kota:

Korzystanie ave uzyskać indeksy minimalnych wierszy w każdej grupie:

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 

Metoda ta ma również potencjalne korzyści z powrotem kilka wierszy na code grupy w instancji wielokrotności wartości są minimalne.

I kolejna metoda z użyciem 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

Gdybyś dodał w zmiennej indeksu, który to zrobił.

library(plyr) 

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

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

z pakietami dplyr i data.table, można wykonać następujące czynności. Możesz uzyskać indeks dla wiersza mającego minimalną wartość dla każdej grupy. Możesz użyć tego w slice(), jeśli używasz dplyr. Jeśli używasz data.table, możesz uzyskać to samo podsumowanie przy użyciu .SD.

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 
Powiązane problemy