简体   繁体   中英

R function to subtract the difference between consecutive values in vector from subsequent values in vector

I have a numerical vector that contains a time series of weight data. What I need to do is remove weight change artifacts by identifying unrealistic differences between consecutive weights and subtracting that change from all subsequent values in the series.

For example, in the series: c(5,4,6,8,8,9,8,12,10,100,101,101), I would identify the delta weight between items 9 and 10 (100 - 10 = 90) as an artifact, and I would correct it by subtracting 90 from the subsequent values, yielding c(5,4,6,8,8,9,8,12,10,10,11,11).

In principal, my code would look something like:

cancel_artifacts <- function(weights, delta_max) {
    for (i in 0:length(weights)) {
        if (weights[i] - weights[i-1] > abs(delta_max)) {
            weights[i:length(weights)] <- weights[i:length(weights)] - (weights[i] - weights[i-1])
        }
    }

Obviously my syntax is a disaster. Can anyone help me set this up?

You can do this in a vectorized manner:

remove_artifacts <- function(weights, delta_max) {
  # calculate deltas, and set first delta to zero
  dw <- c(0, diff(x))
  # create vector of zeros and abs(observations) > delta_max
  # dw * (logical vector) results in either:
  # dw * 0 (if FALSE)
  # dw * 1 (if TRUE)
  dm <- dw * (abs(dw) > delta_max)
  # subtract the cumulative sum of observations > delta_max
  return(weights - cumsum(dm))
}
x <- c(5, 4, 6, 8, 8, 9, 8, 12, 10, 100, 101, 101)
remove_artifacts(x, 50)
# [1]  5  4  6  8  8  9  8 12 10 10 11 11

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM