我有一个data.table
, 和一个日期列表。我希望使用检查日期是否与列表相符的函数来过滤和修改行。
# example data
set.seed(1)
tt <- sample(
seq(as.POSIXct("2011-10-02"), as.POSIXct("2014-04-06"),
by = "day"), 10)
IR1 <- data.table(tstamp = sort(tt), dLoc = 1L:10L)
日期列表:
DLSlist <- lapply(
list(dls11t12 = c("2011-10-02", "2012-04-01"),
dls12t13 = c("2012-10-07", "2013-04-07"),
dls13t14 = c("2013-10-06", "2014-04-06"),
dls14t15 = c("2014-10-05", "2015-04-05"),
dls15t16 = c("2015-10-04", "2016-04-03"),
dls16t17 = c("2016-10-02", "2017-04-02")
),
function(X) as.POSIXct(X)
)
如果dLoc
它落在DLSlist
. 我可以做到以下几点:
IR1[tstamp > DLSlist[[1]][1] & tstamp < DLSlist[[1]][2], tstamp := tstamp + 60*60]
IR1[tstamp > DLSlist[[2]][1] & tstamp < DLSlist[[2]][2], tstamp := tstamp + 60*60]
IR1[tstamp > DLSlist[[3]][1] & tstamp < DLSlist[[3]][2], tstamp := tstamp + 60*60]
然而,这似乎很容易出错:一个函数适合这个任务......我的没有工作。
DLStest <- function(dd, DLSobj) {
any(sapply(DLSobj, function(X) dd %between% X))
}
我将其应用于:
IR1[DLStest(tstamp, DLSlist), tstamp := tstamp + 60*60]
但是它不起作用:所有行都被转换了(不仅是范围内的行,就像我丑陋的黑客代码中的情况一样)。
是否有一些使用函数选择行的方法 - 或其他一些基于多个范围检查选择行的方法?
更新(感谢发现问题的 Frank)
您确实可以使用返回向量或布尔值的函数进行过滤。错误都与我的初始功能有关。
DLStest_old <- function(dd, DLSobj) {
any(sapply(DLSobj, function(X) dd %between% X))
}
sapply
返回一个对象 who's class
is matrix
; any
检查整个. _ matrix
如果有任何真值,则评估为单个TRUE
. 如果不是,则评估为单个FALSE
.
使用测试数据:
(IR1[DLStest_old(tstamp, DLSlist), dLoc := dLoc + 1000L])
tstamp dLoc
1: 2011-11-27 01:00:00 1001
2: 2012-04-03 00:00:00 1002
3: 2012-06-01 00:00:00 1003
4: 2012-09-06 00:00:00 1004
5: 2013-03-09 01:00:00 1005
6: 2013-04-25 00:00:00 1006
7: 2013-05-25 00:00:00 1007
8: 2013-12-29 01:00:00 1008
9: 2014-01-09 01:00:00 1009
10: 2014-02-08 01:00:00 1010
解决方法是分别测试矩阵的每一行,使用apply
.
DLStest <- function(dd, DLSobj) {
apply(sapply(DLSobj, function(X) dd %between% X), 1, any)
}
这现在有效:
> (IR1[DLStest(tstamp, DLSlist), dLoc := dLoc + 1000L])
tstamp dLoc
1: 2011-11-27 01:00:00 1001
2: 2012-04-03 00:00:00 2
3: 2012-06-01 00:00:00 3
4: 2012-09-06 00:00:00 4
5: 2013-03-09 01:00:00 1005
6: 2013-04-25 00:00:00 6
7: 2013-05-25 00:00:00 7
8: 2013-12-29 01:00:00 1008
9: 2014-01-09 01:00:00 1009
10: 2014-02-08 01:00:00 1010