2017-06-13 62 views
2
ve <- c(17, -9, 9, -17, 17, -17, 11, -9, 16, -18, 17, 0, 0, -18, 17, 0, 0, -17, 14, -14, 17, -2, 0, -15, 9, -9, 17, -16, 16, -17, 17, -17, 17, -17, 17, -17, 17, -8, 7, -16, 17, -14, 14, -10, 10, -16, 16, -10, 10, -12, 12, -11, 11, -17, 17, -17, 17, -9, 8, -17, 17, -17, 17, -16, 16, -17, 17, -8, 8, -9, 9, -17, 17, -17, 17, -13, 13, -10, 7, -10, 13, -16, 17, -13, 13, -13, 13, -9, 8, -17, 17, -10, 9, -17, 17, -17, 17, -16, 16, -10, 10, -15, 15, -14, 14, -14, 15, -13, 13, -9, 9, -13, 13, -12, 12, -10, 9, -11, 12, -8, 7, -10, 10, -9, 9, -11, 11, -9, 9, -7, 7, -12, 11, -11, 12, -11, 11, -14, 14, -13, 13, -10, 10, -13, 13, -17, 17, -7, 7, -17, 17, -17, 17, -14, 14, NA) 

df <- data.frame(ve = ve, calc = 0) 

我需要計算在列計算cumsum,但它需要重置爲零,每當它的值變爲負值重新開始.. 我試過幾個條件,但它的復位cumsum沒有真正的工作...如果值變爲負r中

此外,是否有可能在dplyr中實現這一點?我是dplyr的新手,每當需要使用附屬值時,都會覺得有些困難。

謝謝你的幫助!

如果你看到排14和15應該去當..

 ve calc 
1 17 17 
2 -9 8 
3  9 17 
4 -17 0 
5 17 17 
6 -17 0 
7 11 11 
8 -9 2 
9 16 18 
10 -18 0 
11 17 17 
12 0 17 
13 0 17 
14 -18 0 
15 17 17 

,與正常cumsum這將是-1和16 ,但我希望它重置爲0,而不是-1繼續cumsum,因此未來將是17

+0

你想省略'NAs'? – AK88

+0

哦,是的,需要省略NA請 – user5813583

+1

您能否提供示例輸出?我不確定cumsum在達到負值時是如何工作的(例如,從下一個正值開始,包括cumsum中的負值)。 – Marius

回答

1

我們可以replace的NA值是0,並使用cumsum

library(dplyr) 
df1 <- df %>% 
     group_by(grp = cumsum(lag(cumsum(replace(ve, is.na(ve), 0)) < 0, default = TRUE))) %>% 
    mutate(calc = cumsum(replace(ve, is.na(ve), 0)), calc = replace(calc, calc < 0, 0)) %>% 
     ungroup() %>% 
     select(-grp) 
head(df1, 15) 
# A tibble: 15 x 2 
#  ve calc 
# <dbl> <dbl> 
# 1 17 17 
# 2 -9  8 
# 3  9 17 
# 4 -17  0 
# 5 17 17 
# 6 -17  0 
# 7 11 11 
# 8 -9  2 
# 9 16 18 
#10 -18  0 
#11 17 17 
#12  0 17 
#13  0 17 
#14 -18  0 
#15 17 17 
+1

謝謝!它很好用:D – user5813583

1

不使用dplyr,但這應該工作:

ve = as.data.frame(ve) 
ve = na.omit(ve) 
ve$cumS = 0 
ve$cumS[1] = ve$ve[1] 

for (i in 2 : length(ve$ve)) { 

ve$cumS[i] = ifelse((ve$cumS[i - 1] + ve$ve[i]) < 0, 
        0, (ve$cumS[i - 1] + ve$ve[i])) 
} 
+1

這看起來是正確的,但我認爲它失敗了,因爲你的'ifelse'語句實際上沒有做任何事情,你需要將結果分配給've $ cumS [i]'我想。 – Marius

+0

是的,你是對的。會看看。 – AK88

+0

更新了代碼。 – AK88

1

這是一個迭代的解決方案。我想不出如何做到這一點量化/使用dplyr無需多次傳遞過來的數據,但我敢肯定,別人會:

ve_csum = numeric(length(ve)) 

current_total = 0 
for (i in 1:length(ve)) { 
    if (is.na(ve[i])) { 
     ve_csum[i] = current_total 
     next 
    } 
    current_total = current_total + ve[i] 
    if (current_total < 0) { 
     current_total = 0 
    } 
    ve_csum[i] = current_total 
} 

result = data.frame(ve, ve_csum) 
0
> df$calc=ifelse(cumsum(df$ve)<0,0,cumsum(df$ve))