2017-10-07 10 views
3

값이> 0 인 경우에만 누적 평균을 계산하려고합니다. 내가 벡터가있는 경우 :특정 값의 누적 평균

v <- c(1, 3, 0, 3, 2, 0) 

평균 그러나 나는 단지 그것을 9/4 것이 경우에, 그래서 값이> 0 일 때 평균을 먹고 싶어, 9/6 = 1.5 것 = 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을 사용하여 누적 합계를 계산할 수는 있지만 "성공"에 대한 누적 평균은 계산할 수 없습니다.

답변

1

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 

그것은 당신이 너무 tidyverse을 사용할 수

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 

너무 절에서 음의 값으로 작동합니다. 이 솔루션은 데이터가인 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 > 0의 누적 합 v의 누적 합을 나눔으로써이를 해결
+0

확인을 내가 볼 수 있지만 그 자체로 평균이 아닙니다. '1 + 3 + 0/2'는 합계 된 3 개의 값을 나누기 위해 3 개의 값으로 나눠야합니다. 예상 결과에 맞게 답변을 업데이트하겠습니다. – cderv

6

: 범

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