2011-09-26 7 views
8

Wiem, że jest prosty sposób na zrobienie tego ... ale nie mogę tego rozgryźć.Dane zagregowane w jednej kolumnie na podstawie wartości w innej kolumnie

Mam dataframe w moim skryptu R, który wygląda mniej więcej tak:

A  B C 
1.2 4 8 
2.3 4 9 
2.3 6 0 
1.2 3 3 
3.4 2 1 
1.2 5 1 

Należy zauważyć, że A, B i C są nazwy kolumn. I próbuję uzyskać zmienne w ten sposób:

sum1 <- [the sum of all B values such that A is 1.2] 
num1 <- [the number of times A is 1.2] 

Dowolny łatwy sposób to zrobić? Zasadniczo chcę, aby skończyć z ramki danych, które wygląda następująco:

A  num  totalB 
    1.2 3  12 
    etc etc  etc 

Gdzie „num” oznacza liczbę razy szczególności Wartość pojawiły, a „totalB” jest sumą wartości B podano wartość A.

Odpowiedz

13

użyję aggregate dostać dwa agregaty i następnie merge je w jednej ramce danych:

> df 
    A B C 
1 1.2 4 8 
2 2.3 4 9 
3 2.3 6 0 
4 1.2 3 3 
5 3.4 2 1 
6 1.2 5 1 

> num <- aggregate(B~A,df,length) 
> names(num)[2] <- 'num' 

> totalB <- aggregate(B~A,df,sum) 
> names(totalB)[2] <- 'totalB' 

> merge(num,totalB) 
    A num totalB 
1 1.2 3  12 
2 2.3 2  10 
3 3.4 1  2 
+0

łącznie, to po prostu wykorzystuje wszystkie wiersze w moim ramki danych. co, gdybym chciał powiedzieć, by zagregować tylko dla konkretnego wiersza z określonym warunkiem (np. gdy c == 1) – CodeGuy

+0

@CodeGuy: Po prostu 'podzbiór' to, np. 'agregat (B ~ A, podzbiór (df, C == 1), suma)' – NPE

4

Oto rozwiązanie przy użyciu pakietu

plyr::ddply(df, .(A), summarize, num = length(A), totalB = sum(B)) 
4

Tutaj plyr jest rozwiązaniem użycie data.table dla wydajności pamięci i czasu

library(data.table) 
DT <- as.data.table(df) 
DT[, list(totalB = sum(B), num = .N), by = A] 

Aby podzbiór tylko wiersze gdzie C==1 (zgodnie z komentarzem do @aix odpowiedź)

DT[C==1, list(totalB = sum(B), num = .N), by = A] 
1

W dplyr:

library(tidyverse) 
A <- c(1.2, 2.3, 2.3, 1.2, 3.4, 1.2) 
B <- c(4, 4, 6, 3, 2, 5) 
C <- c(8, 9, 0, 3, 1, 1) 

df <- data_frame(A, B, C) 

df %>% 
    group_by(A) %>% 
    summarise(num = n(), 
       totalB = sum(B))