特定值的累积平均值
问题描述:
只有当值大于0时,我才想计算累积平均值。如果我有一个矢量:特定值的累积平均值
v <- c(1, 3, 0, 3, 2, 0)
平均将是9/6 = 1.5,但是我只希望当数值为> 0,所以在这种情况下,这将是9/4到取平均值= 2.25 。但是这个平均值超过了整个集合。随着数据集的建立和积累,我希望做到这一点。所以,最初它会是:
1+3/2, 1+3+0/2, 1+3+0+3/3, 1+3+0+3+2/4, 1+3+0+3+2+0/4
我的数据集是9,000行,它的增长。我可以让cumsum
工作并计算累计总和,但不计算“成功”的累计平均值。
答
dplyr
包具有cummean
功能。如果你只是想为> 0,为v>0
V中选择值:
v <- c(1, 3, 0, 3, 2, 0)
dplyr::cummean(v[v>0])
#> [1] 1.000000 2.000000 2.333333 2.250000
如果你想重复的结果,你可以用食指和从动物园一个辅助功能发挥。
# 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
它与负值的作品以V太
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
你可以使用tidyverse
了。如果您的数据位于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
答
可以通过除以v
的累积和与逻辑矢量v > 0
的累积和解决这个问题:
v1 <- cumsum(v)/cumsum(v>0)
其给出:
> v1 [1] 1.000000 2.000000 2.000000 2.333333 2.250000 2.250000
当你想省略的第一个值:
v2 <- (cumsum(v)/cumsum(v>0))[-1]
其给出:
> v2 [1] 2.000000 2.000000 2.333333 2.250000 2.250000
后者是等于期望的结果如问题指定:
> ref <- c((1+3)/2, (1+3+0)/2, (1+3+0+3)/3, (1+3+0+3+2)/4, (1+3+0+3+2+0)/4)
> identical(v2, ref)
[1] TRUE
数据集中的实现:这给
# create an example dataset
df <- data.frame(rn = letters[seq_along(v)], v)
# calculate the 'succes-cummulative-mean'
library(dplyr)
df %>%
mutate(succes_cum_mean = cumsum(v)/cumsum(v>0))
:
rn v succes_cum_mean 1 a 1 1.000000 2 b 3 2.000000 3 c 0 2.000000 4 d 3 2.333333 5 e 2 2.250000 6 f 0 2.250000
OK我看到,但它是不是平均本身。 '1 + 3 + 0/2'是三个值的总和,所以它应该是三个数值。我会更新答案以符合预期的结果 – cderv