0

I'd like to produce dataframe applied with comprod function ignoring NA

x = data.frame(a=c(NA,1,2,3),b=c(NA,5,6,7))

> cumprod(x)
   a  b
1 NA NA
2 NA NA
3 NA NA
4 NA NA

The result I want is,

> cumprod(x)
   a   b
1 NA  NA
2  1   5
3  2  30
4  6 210

Any simple and efficient idea?

Jaap
  • 81,064
  • 34
  • 182
  • 193
Wookeun Lee
  • 463
  • 1
  • 6
  • 18
  • 2
    Basically the same as [Calculate cumsum() while ignoring NA values](https://stackoverflow.com/questions/25576358/calculate-cumsum-while-ignoring-na-values) – Rich Scriven Aug 18 '17 at 06:02

1 Answers1

2

Anything multiplied by 1 is just itself again, so:

x[] <- lapply(x, function(i) cumprod(replace(i,is.na(i),1)) * ifelse(is.na(i),NA,1) )
x

#   a   b
#1 NA  NA
#2  1   5
#3  2  30
#4  6 210
thelatemail
  • 91,185
  • 12
  • 128
  • 188
  • 1
    `x[] <- lapply(x, function(i) {i[!is.na(i)] <- cumprod(i[!is.na(i)]); i})` is probably more efficient. – Roland Aug 18 '17 at 05:57
  • 2
    Another alternative: `y <- cumprod(replace(x, is.na(x), 1)) ; y[is.na(x)] <- NA`. – mt1022 Aug 18 '17 at 05:59