0

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]

しかし、それは機能しませんでした: すべての行が変換されました (私の醜いハック コードの場合のように、範囲内の行だけではありません)。

関数を使用して行を選択する手段、または複数の範囲チェックに基づいて行を選択する他の手段はありますか?


更新(問題を発見したフランクに感謝します)

実際、ベクトルまたはブール値を返す関数でフィルタリングできます。エラーはすべて私の初期機能にありました。

DLStest_old <- function(dd, DLSobj) {
    any(sapply(DLSobj, function(X) dd %between% X))
}

sapplyのオブジェクトを返しclassますmatrix。全体に真の値があるanyどうかをチェックします。true 値がある場合は、単一の に評価されます。そうでない場合は、単一の に評価されます。matrixTRUEFALSE

テストデータの使用:

(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
4

2 に答える 2