2011-09-26 11 views
8

So che esiste un modo semplice per farlo ... ma non riesco a capirlo.Dati aggregati in una colonna in base ai valori in un'altra colonna

Ho un dataframe nel mio script R che sembra qualcosa di simile:

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 

Nota che A, B, e C sono i nomi delle colonne. E sto cercando di ottenere variabili come questa:

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

Qualsiasi modo semplice per fare questo? Io fondamentalmente voglio finire con un frame di dati che assomiglia a questo:

A  num  totalB 
    1.2 3  12 
    etc etc  etc 

Dove "num" è il numero di volte in quel particolare Un valore apparso, e "totalB" è la somma dei valori B dato il valore A

risposta

13

userei aggregate per ottenere i due aggregati e poi li merge in un singolo fotogramma di dati:

> 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

nel complesso, semplicemente usa tutte le righe nel mio frame di dati. e se volessi dire di aggregare solo per una particolare riga con una particolare condizione (es. quando c == 1) – CodeGuy

+0

@CodeGuy: Semplicemente 'sottoinsieme ', ad es. 'Aggregata (B ~ A, sottoinsieme (df, C == 1), sum)' – NPE

4

Ecco una soluzione che utilizza il pacchetto di plyr

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

Ecco una soluzione utilizzando data.table per la memoria e l'efficienza temporale

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

Per sottoinsieme solo le righe in cui C==1 (come per il commento alla risposta @aix)

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

In 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)) 
Problemi correlati