2011-09-26 14 views
8

Sé que hay una manera fácil de hacer esto ... pero no puedo resolverlo.Datos agregados en una columna basados ​​en valores en otra columna

que tienen una trama de datos en mi script de R que se ve algo como esto:

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 

Tenga en cuenta que A, B, y C son los nombres de columna. Y estoy tratando de obtener variables como esta:

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

¿Alguna manera fácil de hacer esto? Básicamente quiero terminar con una trama de datos que tiene este aspecto:

A  num  totalB 
    1.2 3  12 
    etc etc  etc 

Donde "num" es el número de veces que en particular un valor apareció, y "totalB" es la suma de los valores de B dada el valor A

Respuesta

13

que haría uso de aggregate para obtener los dos agregados y luego merge en una sola trama de datos:

> 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

en el agregado, sólo se utiliza todas las filas en mi trama de datos. ¿y si quisiera decir que se agregue solo para una fila en particular con una condición particular (por ejemplo, cuando c == 1) – CodeGuy

+0

@CodeGuy: simplemente 'subconjúlelo ', p. 'agregado (B ~ A, subconjunto (df, C == 1), suma)' – NPE

4

Aquí es una solución utilizando el paquete de plyr

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

Aquí es una solución utilizando data.table para la eficiencia de la memoria y el tiempo

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

al subconjunto sólo las filas donde C==1 (de acuerdo con el comentario de respuesta @aix)

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

En 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)) 
Cuestiones relacionadas