等到值发生变化再进行计算

Waiting until value changes to make calculation

我有以下数据框:

time <- c(1,2,3,4,5,6,7,8,9,10,11,12)
threshold <- c(1,1,1,0,0,2,2,1,1,2,2,0)
value <- c(5,3,2,4,6,9,1,10,3,5,2,4)

df <- data.frame(time, threshold, value)

threshold 变量背后的逻辑是,当有 1 时:存储第一个值 (5),并在 threshold 变化时减去数字 (4)。在“1”的第一个阈值期间,计算结果为 5 - 4 = 1,应将其存储在新列中 在时间 t=4.

阈值“0”表示不计算。

阈值“2”表示与“1”相反,即初始值 9 减去 10。

目标应该是 table 这样的:

有没有办法在 R 中执行此计算?

如果使用rle函数,您可以关注有阈值变化的行。然后,对齐要减去的值并将阈值转换为控制减法意义的因子。

#Select only rows with a threshold change,
# based on 
compact_threshold <- rle(df$threshold)
row_ids <- cumsum(c(1, compact_threshold$lengths[-length(compact_threshold$lengths)]))

#Transform thresholds to a factor 
# if the row is in a threshold change
df$subFactor <- df$threshold
df$subFactor[-row_ids] <- NA
df$subFactor[df$subFactor==0] <- NA
df$subFactor[df$subFactor==2] <- -1

#Align each value with the one 
# corresponding to the next threshold change
df$value2 <- NA
df$value2[row_ids] <- c(df$value[row_ids][-1], NA)

df$calculation <- (df$value-df$value2)*df$subFactor
#Shift results to the next threshold
df$calculation[row_ids] <- c(NA, df$calculation[row_ids][-length(row_ids)])

df <- df[,c("time", "threshold", "value", "calculation")]
df
#   time threshold value calculation
#1     1         1     5          NA
#2     2         1     3          NA
#3     3         1     2          NA
#4     4         0     4           1
#5     5         0     6          NA
#6     6         2     9          NA
#7     7         2     1          NA
#8     8         1    10           1
#9     9         1     3          NA
#10   10         2     5           5
#11   11         2     2          NA
#12   12         0     1          -4

原始数据

#Data
time <- c(1,2,3,4,5,6,7,8,9,10,11,12)
threshold <- c(1,1,1,0,0,2,2,1,1,2,2,0)
value <- c(5,3,2,4,6,9,1,10,3,5,2,1)

df <-  data.frame(time, threshold, value)
df
#   time threshold value
#1     1         1     5
#2     2         1     3
#3     3         1     2
#4     4         0     4
#5     5         0     6
#6     6         2     9
#7     7         2     1
#8     8         1    10
#9     9         1     3
#10   10         2     5
#11   11         2     2
#12   12         0     1