group_by - sumar datos en r
ddply para la suma por grupo en R (2)
Tengo una muestra de datos "marco" de la siguiente manera:
X Y Month Year income
2281205 228120 3 2011 1000
2281212 228121 9 2010 1100
2281213 228121 12 2010 900
2281214 228121 3 2011 9000
2281222 228122 6 2010 1111
2281223 228122 9 2010 3000
2281224 228122 12 2010 1889
2281225 228122 3 2011 778
2281243 228124 12 2010 1111
2281244 228124 3 2011 200
2281282 228128 9 2010 7889
2281283 228128 12 2010 2900
2281284 228128 3 2011 3400
2281302 228130 9 2010 1200
2281303 228130 12 2010 2000
2281304 228130 3 2011 1900
2281352 228135 9 2010 2300
2281353 228135 12 2010 1333
2281354 228135 3 2011 2340
Quiero usar el ddply
para calcular el ingreso para cada Y
(no X
), si tengo cuatro observaciones para cada Y (por ejemplo, para 2281223 con los meses 6,9,12 de 2010 y el 3 de 2011). Si tengo menos de cuatro observaciones (por ejemplo, para Y = 228130), simplemente quiero ignorarlo. Yo uso los siguientes comandos en R
para el propósito anterior:
require(plyr)
# the data are in the data csv file
data<-read.csv("data.csv")
# convert Y (integers) into factors
y<-as.factor(y)
# get the count of each unique Y
count<-ddply(data,.(Y), summarize, freq=length(Y))
# get the sum of each unique Y
sum<-ddply(data,.(Y),summarize,tot=sum(income))
# show the sum if number of observations for each Y is less than 4
colbind<-cbind(count,sum)
finalsum<-subset(colbind,freq>3)
Mi salida es la siguiente:
>colbind
Y freq Y tot
1 228120 1 228120 1000
2 228121 3 228121 11000
3 228122 4 228122 6778
4 228124 2 228124 1311
5 228128 3 228128 14189
6 228130 3 228130 5100
7 228135 3 228135 5973
>finalsum
Y freq Y.1 tot
3 228122 4 228122 6778
El código anterior funciona, pero requiere muchos pasos. Por lo tanto, me gustaría saber si hay una forma sencilla de realizar la tarea anterior (utilizando el paquete plyr).
Como se señaló en un comentario, puede realizar múltiples operaciones dentro del summarize
.
Esto reduce su código a una línea de ddply()
y una línea de subconjunto, lo cual es bastante fácil con el [
operador:
x <- ddply(data, .(Y), summarize, freq=length(Y), tot=sum(income))
x[x$freq > 3, ]
Y freq tot
3 228122 4 6778
Esto también es excepcionalmente fácil con el paquete data.table
:
library(data.table)
data.table(data)[, list(freq=length(income), tot=sum(income)), by=Y][freq > 3]
Y freq tot
1: 228122 4 6778
De hecho, la operación para calcular la longitud de un vector tiene su propio método abreviado en data.table
: use el .N
abreviado .N
:
data.table(data)[, list(freq=.N, tot=sum(income)), by=Y][freq > 3]
Y freq tot
1: 228122 4 6778
Creo que el paquete dplyr
es más rápido que plyr::ddply
y más elegante.
testData <- read.table(file = "clipboard",header = TRUE)
require(dplyr)
testData %>%
group_by(Y) %>%
summarise(total = sum(income),freq = n()) %>%
filter(freq > 3)