我明白这个问题似乎有些令人困惑。一个例子可能是,
Time x
2017-07-24 12:33:13.000000 0.0
2017-07-24 12:33:14.000000 0.0
2017-07-24 12:33:15.000000 0.0
2017-07-24 12:33:16.000000 0.0
2017-07-24 12:33:16.500000 1.0
2017-07-24 12:33:17.000000 0.0
2017-07-24 12:33:17.500000 0.0
2017-07-24 12:33:18.500000 1.0
在R中,我希望有另一列,对于每一行,计算当前行的时间与x不为0的下一行的时间之间的差异。所以结果如下所示:
Time x diff
2017-07-24 12:33:13.000000 0.0 3.5
2017-07-24 12:33:14.000000 0.0 2.5
2017-07-24 12:33:15.000000 0.0 1.5
2017-07-24 12:33:16.000000 0.0 0.5
2017-07-24 12:33:16.500000 1.0 0.0
2017-07-24 12:33:17.000000 0.0 1.5
2017-07-24 12:33:17.500000 0.0 1.0
2017-07-24 12:33:18.500000 1.0 0.0
感谢您提前回答。
答案 0 :(得分:3)
我认为data.table()库中的Rolling join可以提供帮助。
这是我的解决方案:
首先,让我们设置您的示例数据
library('data.table')
time <- as.POSIXct(c('2017-07-24 12:33:13.000000', '2017-07-24 12:33:14.000000', '2017-07-24 12:33:15.000000', '2017-07-24 12:33:16.000000', '2017-07-24 12:33:16.500000', '2017-07-24 12:33:17.000000', '2017-07-24 12:33:17.500000', '2017-07-24 12:33:18.500000'))
x <- c(0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0)
dat <- data.table(time, x)
现在,为了加入,我们添加一个虚拟列:
dat[, key := 1]
将数据子集设置为x = 1列到新表中
ones <- dat[x==1, list(time, key, ref.time = time)]
请注意,我还会创建一个ref.time
列。这是进行减法的。
设置滚动连接的键
setkey(dat, key, time)
setkey(ones, key, time)
现在进行加入。这回答了问题&#34;原始数据中任何给定行的最近x == 1行是什么&#34;
joined.dat <- ones[dat, roll = -Inf]
计算您寻求的差异
joined.dat[, diff := ref.time - time]
最终输出:
time key ref.time x diff
1: 2017-07-24 12:33:13 1 2017-07-24 12:33:16 0 3.5 secs
2: 2017-07-24 12:33:14 1 2017-07-24 12:33:16 0 2.5 secs
3: 2017-07-24 12:33:15 1 2017-07-24 12:33:16 0 1.5 secs
4: 2017-07-24 12:33:16 1 2017-07-24 12:33:16 0 0.5 secs
5: 2017-07-24 12:33:16 1 2017-07-24 12:33:16 1 0.0 secs
6: 2017-07-24 12:33:17 1 2017-07-24 12:33:18 0 1.5 secs
7: 2017-07-24 12:33:17 1 2017-07-24 12:33:18 0 1.0 secs
8: 2017-07-24 12:33:18 1 2017-07-24 12:33:18 1 0.0 secs
答案 1 :(得分:2)
查找“x == 1”的行:
wh = which(dat$x == 1)
我们可以建立一个最近(前向)“1”的索引向量:
i = rep(wh, c(wh[1], diff(wh)))
然后减去相应的“时间”:
dat$Time[i] - dat$Time
#Time differences in secs
#[1] 3.5 2.5 1.5 0.5 0.0 1.5 1.0 0.0
“dat”是:
dat = structure(list(Time = structure(c(1500888793, 1500888794, 1500888795,
1500888796, 1500888796.5, 1500888797, 1500888797.5, 1500888798.5
), class = c("POSIXct", "POSIXt"), tzone = ""), x = c(0, 0, 0,
0, 1, 0, 0, 1)), .Names = c("Time", "x"), row.names = c(NA, 8L
), class = "data.frame")
答案 2 :(得分:0)
使用Base R和vectorization:
a <- c(1, 3, 6, 10, 15, 17, 20, 23, 34)
b <- c(0, 0, 0, 1, 0, 1, 0, 0, 1)
手工答案应该是这样的:
c <- c(9, 7, 4, 0, 2, 0, 14, 11, 0)
创建一个向量,其中b中的值是'pivotots'。我们还附加0作为起点:
pivots <- c(0, which(b != 0))
最后,重复这些支点,因为值0
和下一个1
之间存在多次。
vec <- rep(a[pivots], times = diff(pivots)
identical(c, vec - a)
如果您想将此转换为带values
向量/列和pivots
向量/列的函数,您可以执行以下操作:
diffToNextPivot <- function(values, pivots) {
pivots <- c(0, which(pivots != 0))
vec <- rep(values[pivots], times = diff(pivots))
vec - values
}
myDataFrame$diff <- diffToNextPivot(myDataFrame$Time, myDataFrame$x)