Ddply для суммы по группе в R
У меня есть пример данных "данных" данных следующим образом:
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
Я хочу использовать ddply
для вычисления дохода для каждого Y
(не X
), если у меня есть четыре наблюдения для каждого Y (например, для 2281223 с месяцами 6,9,12 2010 года и 3 месяца 2011 года). Если у меня меньше четырех наблюдений (например, для Y = 228130), я хочу просто игнорировать его. Я использую следующие команды в R
для указанной цели:
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)
Мой вывод выглядит следующим образом:
>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
Приведенный выше код работает, но требует много шагов. Итак, я хотел бы знать, есть ли простой способ выполнить вышеупомянутую задачу (используя пакет plyr).
Ответы
Ответ 1
Как указано в комментарии, вы можете выполнять несколько операций внутри summarize
.
Это уменьшает ваш код до одной строки ddply()
и одной строки подмножества, что достаточно просто с оператором [
:
x <- ddply(data, .(Y), summarize, freq=length(Y), tot=sum(income))
x[x$freq > 3, ]
Y freq tot
3 228122 4 6778
Это также очень просто с пакетом 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
Фактически, операция вычисления длины вектора имеет свой собственный ярлык в data.table
- используйте ярлык .N
:
data.table(data)[, list(freq=.N, tot=sum(income)), by=Y][freq > 3]
Y freq tot
1: 228122 4 6778
Ответ 2
Я думаю, что пакет dplyr
быстрее, чем plyr::ddply
и более элегантный.
testData <- read.table(file = "clipboard",header = TRUE)
require(dplyr)
testData %>%
group_by(Y) %>%
summarise(total = sum(income),freq = n()) %>%
filter(freq > 3)