具有各种IF的向量,加和减

时间:2018-12-04 11:29:57

标签: r cumulative-sum

我有一个向量

x <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11)

现在,如果向量x为负,则必须累积向量y;当向量x为负时,则需要累积向量y,直到回到零:

y <- c(0,0,-4,-10,-12,-11,-7,-5,-8,-14,-15,-7,0,0,-6,-17)

以下是需要遵守的条件:

  • 负值和正值的累加总和,只要总和小于0

  • 如果总和为正,则停止累积总和,直到达到以下负值为止。

  • 当总和为正数时,打印值为0。

感谢帮助!

3 个答案:

答案 0 :(得分:4)

我认为此计算对于矢量化而言并非易事,因为元素以非平凡的方式依赖于先前的元素,因此最好的方法可能只是使用循环:

x <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11)

y <- pmin(x,0) # gives us the first element correctly, and the correct vector length
for (i in seq_along(x[-1])) y[i+1] <- pmin(y[i] + x[i+1], 0)

y

# [1]   0   0  -4 -10 -12 -11  -7  -5  -8 -14 -15  -7   0   0  -6 -17

答案 1 :(得分:3)

x <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11)

for (i in seq_along(x)) { x[i] = ifelse(sum(x[(i-1):i]) > 0, 0, sum(x[(i-1):i])) }

x

# [1]   0   0  -4 -10 -12 -11  -7  -5  -8 -14 -15  -7   0   0  -6 -17

另一种方法是像这样使用Reduce

Reduce(function(u, v) ifelse(sum(c(u, v)) > 0, 0, sum(c(u, v))), x, accumulate = T, init = x[1])[-1]

#  [1]   0   0  -4 -10 -12 -11  -7  -5  -8 -14 -15  -7   0   0  -6 -17

如果要将该过程应用于每一列,可以使用以下示例:

# example dataset
df = data.frame(x = c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11),
                y = c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11),
                z = c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11))

# function to update columns
UpdateColumn = function(x) { 
  for (i in seq_along(x)) { x[i] = ifelse(sum(x[(i-1):i]) > 0, 0, sum(x[(i-1):i])) }
  x
                            }

# apply function to each column
# save as data frame
data.frame(sapply(df, UpdateColumn))

#      x   y   z
# 1    0   0   0
# 2    0   0   0
# 3   -4  -4  -4
# 4  -10 -10 -10
# 5  -12 -12 -12
# 6  -11 -11 -11
# 7   -7  -7  -7
# 8   -5  -5  -5
# 9   -8  -8  -8
# 10 -14 -14 -14
# 11 -15 -15 -15
# 12  -7  -7  -7
# 13   0   0   0
# 14   0   0   0
# 15  -6  -6  -6
# 16 -17 -17 -17

答案 2 :(得分:0)

据我所知,没有办法专门针对R。只需使用for循环即可。

x <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11)
n<-length(x)
y<-numeric(n)
y[1]<-min(x[1],0)
for(i in 2:n){
  y[i]<-min(0,y[i-1]+x[i])
}

 y
 #[1]   0   0  -4 -10 -12 -11  -7  -5  -8 -14 -15  -7   0   0  -6 -17