2

これは、「日付が別のオブジェクトの 2 つの日付の間にあるかどうかをチェックする R: For() ループ」の再投稿であり、Henrik と Metrics の提案を受けて最小限のモック/テストを組み込むように変更されています。彼らのおかげです。

2 つの大きなデータセットがあり、どちらにも日付/時刻フィールドの列が含まれています。最初のデータセットには 1 つの日付があり、2 番目のデータセットには 2 つの日付があります。つまり、最初のデータ セットから、2 番目の他の 2 つの日付の間にあるすべての日付を見つけて、平均値を見つけようとしています。わかりやすくするために、日付ではなく値を使用して最小限の模擬データ セットを作成しました。

最初のモック データ セットの head() と dput() の出力を以下に示します。このデータは、IndID 列で示される個人に固有のものです。

  IndID MockDate RandNumber
1     1        5   1.862084
2     1        3   1.103154
3     1        5   1.373760
4     1        1   1.497397
5     1        1   1.319488
6     1        3   2.120354

actData <- structure(list(IndID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L), MockDate = c(5L, 3L, 5L, 1L, 1L, 3L, 4L, 
2L, 2L, 5L, 2L, 1L, 5L, 3L, 5L, 3L, 5L, 3L, 5L, 1L, 5L, 3L, 5L, 
5L, 2L, 3L, 1L, 4L, 3L, 3L), RandNumber = c(1.862083679, 1.103154127, 
1.37376001, 1.497397482, 1.319487885, 2.120353884, 1.895660195, 
1.150411874, 2.61036961, 1.99354158, 1.547706758, 1.941501873, 
1.739226419, 2.455590044, 2.907382515, 2.110502618, 2.076187012, 
2.507527308, 2.167657681, 1.662405916, 2.428807116, 2.04699653, 
1.937335768, 1.456518889, 1.948952907, 2.104325112, 2.311519732, 
2.092650229, 2.109051215, 2.089144475)), .Names = c("IndID", 
"MockDate", "RandNumber"), class = "data.frame", row.names = c(NA, 
-30L))

2 番目のモック データ セットの head() と dput() の出力を以下に示します。

 IndID StartTime EndTime
1     1         4       5
2     1         7      11
3     1         6       9
4     1         7       9
5     1         6      10
6     1         2      12

clstrData <- structure(list(IndID.1 = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), StartTime = c(4L, 7L, 
6L, 7L, 6L, 2L, 6L, 4L, 3L, 5L, 2L, 5L, 7L, 3L, 4L, 3L, 2L, 5L, 
5L), EndTime = c(5L, 11L, 9L, 9L, 10L, 12L, 8L, 13L, 5L, 13L, 
9L, 9L, 17L, 6L, 8L, 6L, 9L, 15L, 7L)), .Names = c("IndID", 
"StartTime", "EndTime"), row.names = c(NA, 19L), class = "data.frame")

2 番目のデータセットには、開始時刻と終了時刻を表す 2 つの数値フィールドがあります。上記のように、これらのデータは、IndD 列に記載されている個人にも固有のものです。

「MockDate」が一意の IndID ごとに 2 番目のデータセットの「StartTime」と「EndTime」の間にある場合、すべてのインスタンスについてデータセット 1 の「RandNumber」を平均化する必要があります。したがって、「RandNumber」値は、1) 「StartTime」と「EndTime」の範囲内にあり、2) 両方の行の IndID が同じである場合にのみ平均化する必要があります。

MockDate が StartTime と EndTime の間にある場合に ID を指定する関数を作成することから始めました。

is.between <- function(x, a, b) {
    x > a & x < b
}

関数が単一の値に対して機能することをテストする is. between(actData[1,3], clstrData[,2], clstrData[,3])

しかし、これをすべての行に対してループして平均を見つける方法がわかりません。私の for() ループの始まりは以下です。

YesNo <- list()
for (i in 1:nrow(actData)) {
YesNo[[i]] <- is.between(actData[1,3], clstrData[,2], clstrData[,3])
}
YesNo[[3]]

この for() は、すべての行に対して同じ結果を返します…</p>

作成したいと考えています... clstrData$NEWcolum <-各行の RandNum を意味します。

ありがとう、そしていつものようにどんな提案も大歓迎です!

4

2 に答える 2

2

マシンがデータ サイズを処理できると仮定すると、次のことができます。

  • ID の 2 つのデータ フレームをマージしてから、
  • それに応じてグループ化します (つまり、IndID、開始日と終了日によって)
  • モック日付が終了日の間にある行の平均を計算します

ここにいくつかのコードがありますdata.table

library(data.table)
DT.clstr <- data.table(clstrData, key="IndID")
DT.act   <- data.table(actData, key="IndID")

# Adjust to `<=` if needed
ComputedDT <- 
  merge(DT.clstr, DT.act, allow.cartesian=TRUE)[
      MockDate > StartTime &  MockDate < EndTime
    , list(Mean=mean(RandNumber))
    , by=list(IndID, StartTime, EndTime)
    ]

結果

ComputedDT

   IndID StartTime EndTime     Mean
1:     1         2      12 1.671002
2:     2         4      13 2.176799
3:     2         2       9 2.244702
4:     3         3       6 1.978828
5:     3         4       8 1.940887
6:     3         2       9 2.033104
于 2013-09-17T21:58:09.630 に答える
1

以前の考えについて、Ricardo Saporta に感謝します。

ただし、for() ループで長い条件を作成するのが最良の選択肢でした。ただし、data.table() ほど高速ではありません。

上記のデータを使用して、以下のコードは最終的に構築したものです。

clstrData$meanAct = rep(NA, nrow(clstrData))

for (i in 1:nrow(clstrData)){
    clstrData$meanAct[i] = mean(actData$RandNumber[actData$IndID==clstrData$IndID[i]
    &is.between(actData$RandNumber, clstrData$StartTime[i], clstrData$EndTime[i])])
    }
head(clstrData)
tail(clstrData)

開始時間と終了時間の間に対応する値がない場合、NAN が生成されます。

于 2013-09-18T19:39:16.237 に答える