我在R中有一个数据框,它与此相似:
time value
13-07-2019 02:34:28 9.07
13-07-2019 02:34:57 8.87
13-07-2019 02:35:27 9.34
13-07-2019 02:46:08 X
13-07-2019 02:46:38 4.5
13-07-2019 02:47:08 6.66
13-07-2019 02:47:37 8.7
13-07-2019 02:48:08 4.7
13-07-2019 02:48:39 X
13-07-2019 02:49:08 7.8
13-07-2019 02:49:39 9.8
13-07-2019 02:50:38 X
13-07-2019 02:51:08 2.34
13-07-2019 02:51:39 5.67
13-07-2019 02:52:08 X
13-07-2019 02:52:38 8.766
13-07-2019 02:53:08 5.456
13-07-2019 02:53:38 X
13-07-2019 02:54:08 6.544
13-07-2019 02:54:39 9.877
13-07-2019 02:55:08 X
我想要的是找出x时的最近时间。例如:
13-07-2019 02:35:27 9.34
13-07-2019 02:46:08 X
13-07-2019 02:46:38 4.5
这里X的最近时间是13-07-2019 02:46:38
13-07-2019 02:53:08 5.456
13-07-2019 02:53:38 X
13-07-2019 02:54:08 6.544
这里是13-07-2019 02:53:08
我只需要考虑30秒以内的时间。如果超过30秒,我会认为时间是之前的30秒
13-07-2019 01:53:08 5.456
13-07-2019 02:53:38 X
13-07-2019 04:54:08 6.544
在这里,我需要将时间限制为:13-07-2019 02:53:08
,这是较低的30秒,因为它的差值超过30秒。
最后,我需要获取一个具有n个值的数据框,其中n是我在数据框值列中拥有x
的次数
答案 0 :(得分:2)
由于您用data.table
标记了问题,
这是一个假设您有一个选择
(此处命名为dt
)
和你的时间是弦
(如果已经POSIXct
,请跳过第一行):
dt[, time := as.POSIXct(time, format = "%d-%m-%Y %H:%M:%S")]
max_difftime <- as.difftime(30L, units = "mins")
lambda <- function(rolled_time, x_time) {
invalid <- abs(rolled_time - x_time) > max_difftime
if (any(invalid)) {
rolled_time[invalid] <- x_time[invalid] - max_difftime
}
rolled_time
}
dt[value != "X"
][dt[value == "X"],
.(x_time = i.time, time = lambda(x.time, i.time)),
on = "time",
roll = "nearest"]
x_time time
1: 2019-07-13 02:46:08 2019-07-13 02:46:38
2: 2019-07-13 02:48:39 2019-07-13 02:49:08
3: 2019-07-13 02:50:38 2019-07-13 02:51:08
4: 2019-07-13 02:52:08 2019-07-13 02:51:39
5: 2019-07-13 02:53:38 2019-07-13 02:53:08
6: 2019-07-13 03:24:40 2019-07-13 02:54:40
我对示例数据进行了一些修改,以使最后一行具有03:24:40
。
代码在value
为X
的行与其余行之间执行滚动连接,
寻找最近的time
。
lambda
函数比较找到的最近时间
(由x.time
公开为data.table
)
与找到X
的时间
(由i.time
公开为data.table
),
并调整时差大于30分钟的值。
我添加了x_time
列只是为了显示比较,
您可以在不需要时删除它。
答案 1 :(得分:0)
如果您只是在+ -30秒内计算没有非NA值的X数,则可以
1)使用非等额联接:
DT[!is.na(value)][
DT[is.na(value), .(now=time, start=time-30, end=time+30)],
on=.(time>=start, time<=end), .(time=now, .N>0), by=.EACHI][,
sum(V2)]
2)使用between
:
start <- DT2[!is.na(value), time-30]
end <- DT2[!is.na(value), time+30]
DT2[is.na(value), sum(sapply(time, function(x) !any(between(x, start, end))))]
数据:
library(data.table)
DT <- fread("time,value
13-07-2019 02:34:28,9.07
13-07-2019 02:34:57,8.87
13-07-2019 02:35:27,9.34
13-07-2019 02:46:08,NA
13-07-2019 02:46:38,4.5
13-07-2019 02:47:08,6.66
13-07-2019 02:47:37,8.7
13-07-2019 02:48:08,4.7
13-07-2019 02:48:39,NA
13-07-2019 02:49:08,7.8
13-07-2019 02:49:39,9.8
13-07-2019 02:50:38,NA
13-07-2019 02:51:08,2.34
13-07-2019 02:51:39,5.67
13-07-2019 02:52:08,NA
13-07-2019 02:52:38,8.766
13-07-2019 02:53:08,5.456
13-07-2019 02:53:38,NA
13-07-2019 02:54:08,6.544
13-07-2019 02:54:39,9.877
13-07-2019 02:55:08,NA
14-07-2019 01:53:08,5.456
14-07-2019 02:53:38,NA
14-07-2019 04:54:08,6.544")
DT[, time := as.POSIXct(time, format = "%d-%m-%Y %H:%M:%S")]
DT2 <- copy(DT)