删除R

时间:2018-12-16 23:26:15

标签: r

我需要计算数据集中每个用户的总数,但问题是,即使用户的数量为0,它也会不断减去并生成假的负值(错误的数量不能小于0 )。

对于每个+或-都有真实的事件。但是,当金额达到0时,无论出现多少否定事件,结果都不应低于0,并且如果我们有前10个否定事件,例如转到-1000,之后我们有一个正数+200,然后是一个负数-100,我需要最终结果为100。

在此示例,该用户的最终总金额应为200。

userdata <- read.table(text="
 ID  Amount UserID Date     Hour
 1   500    2      3/3/2018 0:00
 2  -200    2      3/4/2018 0:00
 3  -250    2      3/5/2018 0:00
 4  -500    2      3/8/2018 0:00
 5   100    2      3/8/2018 0:00
 6  -50     2      3/8/2018 0:00
 7   250    2      3/8/2018 0:00
 8  -100    2      3/8/2018 0:00
", header=TRUE, stringsAsFactors=FALSE)

我需要一种正确计算该金额的方法。

2 个答案:

答案 0 :(得分:1)

我认为我们可以使用递归过滤器(一种有条件的累加和)来解决这个问题。

# Isolate the vector we're interested in and prepend a zero
y <- c(0, userdata$Amount)

# run a for loop
for (i in 2:length(y)) {   # For every position in the vector, 
    y[i] <- y[i-1] + y[i]  # add the previous to the present.
    if (y[i] < 0) {        # If the resulting sum is less than zero,
        y[i] <- 0          # replace it with zero
    }
}

# Or equivalent, but maybe a bit more elegant
for (i in 2:length(y)) { 
    y[i] <- max(c(0, y[i-1] + y[i]))
}

y[-1]
# [1] 500 300  50   0 100  50 300 200  

tail(y, 1)
# 200

答案 1 :(得分:1)

如果我理解正确,那么总金额就不会累积为负。

尽管AkselA's recursive filter通过遍历向量的元素来计算总计,但是下面的方法在累加和变为负数时会对其进行迭代校正。请注意,元素的顺序很重要,例如时间序列。

nonneg_cumsum <- function(x) {
  n <- length(x)
  y <- cumsum(x)
  repeat {
    i <- head(which(y < 0), 1L)
    if (length(i) < 1) return(y)
    y[i:n] <- y[i:n] - y[i]
  }
}

nonneg_cumsum(userdata$Amount)
[1] 500 300  50   0 100  50 300 200

为进行比较,以下是常规cumsum()函数的输出:

cumsum(userdata$Amount)
[1]  500  300   50 -450 -350 -400 -150 -250