dplyr package have a cummean function. If you want only for > 0, select value in v for v>0:
v <- c(1, 3, 0, 3, 2, 0)
dplyr::cummean(v[v>0])
#> [1] 1.000000 2.000000 2.333333 2.250000
if you want the results with repetition, you could play with index and a helper function from zoo.
# Create a vector container for the result (here with NA values)
v_res <- v[NA]
# Fill cumsum where you want to calculate it (here v>0)
v_res[v>0] <- dplyr::cummean(v[v>0])
# Fill the gap with previous value
zoo::na.locf(v_res)
#> [1] 1.000000 2.000000 2.000000 2.333333 2.250000 2.250000
it works with negative value in v too
v <- c(1, 3, 0, 3, -5, 2, 0, -6)
v_res <- v[NA]
v_res[v>0] <- dplyr::cummean(v[v>0])
zoo::na.locf(v_res)
#> [1] 1.000000 2.000000 2.000000 2.333333 2.333333 2.250000 2.250000 2.250000
You could use tidyverse too. This solution could be useful if your
data is in a data.frame.
library(dplyr, warn.conflicts = F)
library(tidyr)
data <- data_frame(v = c(1, 3, 0, 3, 2, 0)) %>%
tibble::rowid_to_column()
res <- data %>%
filter(v > 0) %>%
mutate(cummean = cummean(v)) %>%
right_join(data, by = c("rowid", "v")) %>%
fill(cummean)
res
#> # A tibble: 6 x 3
#> rowid v cummean
#> <int> <dbl> <dbl>
#> 1 1 1 1.000000
#> 2 2 3 2.000000
#> 3 3 0 2.000000
#> 4 4 3 2.333333
#> 5 5 2 2.250000
#> 6 6 0 2.250000
pull(res, cummean)[-1]
#> [1] 2.000000 2.000000 2.333333 2.250000 2.250000