为R中具有相同符号的每个连续数字范围分配值

hfi*_*sch 7 diff aggregate r transform sign

我正在尝试创建一个数据框,其中存在一个列,其中包含表示正数和负数运行长度的值,如下所示:

Time  V  Length
0.5  -2  1.5
1.0  -1  1.5
1.5   0  0.0
2.0   2  1.0
2.5   0  0.0
3.0   1  1.75
3.5   2  1.75
4.0   1  1.75
4.5  -1  0.75
5.0  -3  0.75
Run Code Online (Sandbox Code Playgroud)

Length列汇总了值为正或负的时间长度.0因为它们是拐点,所以给出零.如果符号变化没有零分离,则在拐点的任一侧平均值.

我试图估计这些价值观积极或消极的时间.我试过这个for循环有不同程度的成功,但我想避免循环,因为我正在处理非常大的数据集.

我花了一些时间看signdiff,因为他们在使用约符号改变这个问题.我也看过这个使用transformaggregate连续重复值的问题.我觉得我可以结合使用sign和/或diff,但我不确定如何追溯性地将这些总和分配到创建它们的范围或如何处理我在整个变形中取平均值的点.

任何建议,将不胜感激.以下是示例数据集:

dat <- data.frame(Time = seq(0.5, 5, 0.5), V = c(-2, -1, 0, 2, 0, 1, 2, 1, -1, -3))
Run Code Online (Sandbox Code Playgroud)

Hen*_*rik 3

首先找到需要插值的“Time”索引:正值和负值之间缺少零的连续“V”;他们的人数abs(diff(sign(V))等于二。

id <- which(abs(c(0, diff(sign(dat$V)))) == 2)
Run Code Online (Sandbox Code Playgroud)

将相关索引之间的平均“时间”和相应的“V”值为零的行添加到原始数据中。还要在“Time”= 0 处和最后一个时间步添加“V”= 0 行(根据@Gregor 提到的假设)。按“时间”排序。

d2 <- rbind(dat,
            data.frame(Time = (dat$Time[id] + dat$Time[id - 1])/2, V = 0),
            data.frame(Time = c(0, max(dat$Time)), V = c(0, 0))
            )
d2 <- d2[order(d2$Time), ]
Run Code Online (Sandbox Code Playgroud)

计算为零的时间步之间的时间差,并使用“零组索引”复制它们。

d2$Length <- diff(d2$Time[d2$V == 0])[cumsum(d2$V == 0)]
Run Code Online (Sandbox Code Playgroud)

将值添加到原始数据:

merge(dat, d2)

#    Time  V Length
# 1   0.5 -2   1.50
# 2   1.0 -1   1.50
# 3   1.5  0   1.00
# 4   2.0  2   1.00
# 5   2.5  0   1.75
# 6   3.0  1   1.75
# 7   3.5  2   1.75
# 8   4.0  1   1.75
# 9   4.5 -1   0.75
# 10  5.0 -3   0.75
Run Code Online (Sandbox Code Playgroud)

将“长度”设置为0where V == 0