1

次の (例)zooオブジェクトを考えてみましょう。

動物園のオブジェクトの例

データ フレームは、日付インデックスで昇順に並べ替えられます。ma3フィールドは、期間フィールドの3 日間の移動平均値を提供します。比較フィールドは、期間値の値対応するma3値と比較します。(1) IF期間> ma3 THEN 'ABOVE'、(2) IF期間< ma3 THEN 'BELOW'、(3) ELSE 'EQUAL'。

consec_dayフィールドの値は次のように計算されます。比較値が「ABOVE」に等しい場合はma3 値を持つ最も古い日付から開始し、 consec_day値の符号は正であり、比較値が「BELOW」に等しい場合は符号consec_day値は負であり、比較が「EQUAL」に等しい場合、consec_dayはゼロです。consec_day値の大きさを判断するには、連続する (最も古いものから最新のものまで) 同一の比較値の数を数えます。

質問:

  1. consec_dayフィールドの計算はベクトル化できますか?
  2. もしそうなら、どのように?

私の現在のソリューションは、次のようにループを使用しています。

    z0 <- zoo(matrix(c(c(345, 432, 112, 332, 496, 414, 211), c(NA, NA, 296.33, 292, 313.33, 414, 373.67), c(NA, NA, 'BELOW', 'ABOVE', 'ABOVE', 'EQUAL', 'BELOW'), c(NA, NA, -1, 1, 2, 0, -1)), nrow = 7, ncol = 4), seq(as.Date('2013-07-31'), as.Date('2013-08-06'), by = "day"))
    colnames(z0) <- c("duration", "ma3", "comparison", "consec_day")
    require(xts)
    for (r in 1:nrow(z0)) {
      if (is.na(z0$comparison[r])) {next}
      if (z0$comparison[r] == 'EQUAL') {z0$consec_day[r] <- 0; next}
      if (is.na(z0$comparison[r - 1])) {z0$consec_day[r] <- ifelse(z0$comparison[r] == 'ABOVE', 1, ifelse(z0$comparison[r] == 'BELOW', -1, 0)); next}
      if ( (xts::coredata(df0)[r, 3] != xts::coredata(df0)[r - 1, 3]) & xts::coredata(df0)[r, 3] == 'ABOVE') {
        df0$consec_day[r] <- 1 
      } else {
      if ( (xts::coredata(df0)[r, 3] != xts::coredata(df0)[r - 1, 3]) & xts::coredata(df0)[r, 3] == 'BELOW') {
        df0$consec_day[r] <- -1 
      } else {ifelse((xts::coredata(df0)[r, 3] != xts::coredata(df0)[r - 1, 3]) & xts::coredata(df0)[r, 3] == 'ABOVE')), df0$consec_day[r] <- df0$consec_day[r - 1] + 1, df0$consec_day[r] <- df0$consec_day[r - 1] - 1}
    }
4

1 に答える 1