2013-09-12 5 views
3

Как сделать расчет на основе результата предыдущей строки в R? Чтобы сделать его более четко, представьте себе следующую dataframe:Некоторые конкретные вычисления в data.frame

user rev total_rev 
A  10 10 
A  10 20 
A  20 40 
A  10 50 
B  50 50 
C  50 50 
C  10 60 
C  20 80 

где пользователь уникальный идентификатор переменной и оборотов метрической переменной (например, доход), который я хочу объединить в новую переменную «total_rev» , Он должен содержать сумму переменной «оборот» до определенной линии, таким образом коснуться как следующий расчет должен проводиться для каждой строки:

> total_rev[i] = total_rev[i-1] + rev[i] 

где я фактическая линию

Обратите внимание, что расчет должен начинаться с нуля для каждого пользователя. Я уже пытался решить эту проблему с помощью цикла, который работал на небольшой тестовой площадке, но датфрейм довольно велик, и вычисления в полном наборе данных просто не хотят заканчиваться.

+2

Добро пожаловать в SO. Этот вопрос очень прост и должен быть разрешен из нескольких быстрых исследований с вашей стороны. «R» векторизован и обладает замечательными инструментами агрегирования. Оглянитесь здесь немного, а google - за кумулятивные суммы и стратегию манипулирования данными «split-apply-comb». – Justin

ответ

0
library(plyr) 
mydata<-mtcars 
ddply(mydata,.(cyl),transform,mpg=cumsum(mpg)) 

Для ваших данных:

library(plyr) 
ddply(yourdata,.(user),transform,total_rev=cumsum(rev)) 

user rev total_rev 
1 A 10  10 
2 A 10  20 
3 A 20  40 
4 A 10  50 
5 B 50  50 
6 C 50  50 
7 C 10  60 
8 C 20  80 
+1

Большое спасибо, работает отлично! :) – user2635656

2

Вы можете использовать ?ave и ?cumsum:

ave(df$rev, df$user, cumsum) 

т.д .:

df <- read.table(textConnection("user rev total_rev 
A  10 10 
A  10 20 
A  20 40 
A  10 50 
B  50 50 
C  50 50 
C  10 60 
C  20 80"), header=TRUE) 

df$total <- ave(df$rev, df$user, cumsum) 
# user rev total_rev total 
#1 A 10  10 10 
#2 A 10  20 20 
#3 A 20  40 40 
#4 A 10  50 50 
#5 B 50  50 50 
#6 C 50  50 50 
#7 C 10  60 60 
#8 C 20  80 80 
3

Когда имеешь дело с огромной базой данных, data.table является хорошим вариантом

> library(data.table) 
> DT <- data.table(df) 
> DT[, total:= cumsum(rev), by=list(user) ] 
> DT 
    user rev total_rev total 
1: A 10  10 10 
2: A 10  20 20 
3: A 20  40 40 
4: A 10  50 50 
5: B 50  50 50 
6: C 50  50 50 
7: C 10  60 60 
8: C 20  80 80 
Смежные вопросы