简体   繁体   中英

Finding cumulative product if a certain condition is met in R

I have a dataset that looks like the following (called Data):

v1 v2
1   1  
1   3
1   5
2   3
2   4
3   1
3   2

I want to return a vector v3 that:

  • is equal to v2[i] if v1[i] is not equal to v1[i-1]
  • is equal to v3[i-1]*v2[i] if v1[i] is equal to v1[i-1]

So, in this example, v3 should return

v3
1
3
15
3
12
1
2

I've lagged the column v1 by using lag.v1<-c(NA,Data[1:nrow(Data)-1,1]) in order to compare to the previous row. I think something similar to the following should work, but with the value of v3 in the previous row instead of the current row.

Data$v3<-ifelse(1*(Data$v1==lag.v1)==1, Data$v3*Data$v2, Data$v2)

In other words, I need to somehow access the previous row of v3 (lag v3) as I'm forming v3 in the above equation.

Help is greatly appreciated, thank you!

You can use ave with cumprod , this calculates the cumulative product of column v2 grouped by v1 :

df$v3 <- with(df, ave(v2, v1, FUN=cumprod))

df
#  v1 v2 v3
#1  1  1  1
#2  1  3  3
#3  1  5 15
#4  2  3  3
#5  2  4 12
#6  3  1  1
#7  3  2  2

With plyr package, you can use ddply with transform :

plyr::ddply(df, "v1", transform, v3 = cumprod(v2))

#  v1 v2 v3
#1  1  1  1
#2  1  3  3
#3  1  5 15
#4  2  3  3
#5  2  4 12
#6  3  1  1
#7  3  2  2

If you haven't, you probably also want to know a dplyr approach:

library(dplyr)
df %>% group_by(v1) %>% mutate(v3 = cumprod(v2))

#Source: local data frame [7 x 3]
#Groups: v1 [3]

#     v1    v2    v3
#  <int> <int> <dbl>
#1     1     1     1
#2     1     3     3
#3     1     5    15
#4     2     3     3
#5     2     4    12
#6     3     1     1
#7     3     2     2

We can use data.table

library(data.table)
setDT(df)[, v3 := cumprod(v2), by = v1]
df
#   v1 v2 v3
#1:  1  1  1
#2:  1  3  3
#3:  1  5 15
#4:  2  3  3
#5:  2  4 12
#6:  3  1  1
#7:  3  2  2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM