4

一部の行を空のままにして(特定の条件が満たされていない場合)、複数の連続する行をグループ化(およびそれらに同じ値を割り当て)しようとしています。

私のデータは、位置 (xy 座標)、それらが測定された日時、および測定間の時間間隔です。どういうわけか単純化すると、次のようになります。

ID   X     Y      Time    Span
1    3445  7671   0:00    -
2    3312  7677   4:00    4
3    3309  7680   12:00   8
4    3299  7681   16:00   4
5    3243  7655   20:00   4
6    3222  7612   4:00    8
7    3260  7633   0:00    4
8    3254  7641   8:00    8
9    3230  7612   0:00    16
10   3203  7656   4:00    4
11   3202  7678   8:00    4
12   3159  7609   20:00   12
...

4 時間以内に測定されたすべての一連の場所に値を割り当て、データを次のように表示したいと考えています。

ID   X     Y      Time    Span  Sequence
1    3445  7671   0:00    -     -
2    3312  7677   4:00    4     1
3    3309  7680   12:00   8     NA
4    3299  7681   16:00   4     2
5    3243  7655   20:00   4     2
6    3222  7612   4:00    8     NA
7    3260  7633   0:00    4     3
8    3254  7641   8:00    8     NA
9    3230  7612   0:00    16    NA
10   3203  7656   4:00    4     4
11   3202  7678   8:00    4     4
12   3159  7609   20:00   12    NA

次のようなループ「for」と「ifelse」条件を使用して、いくつかのアルゴリズムを試しました。

Sequence <- for (i in 1:max(ID)) {
ifelse (Span <= 4, i+1, "NA")
}

運がなければ。私の試みが間違っていることはわかっていますが、私のプログラミング スキルは非常に基本的なものであり、Web で同様の問題を見つけたことはありません。

どんなアイデアでも大歓迎です!

4

3 に答える 3

7

これは長めのワンライナーです:

ifelse(x <- DF$Span == 4, cumsum(c(head(x, 1), tail(x, -1) - head(x, -1) == 1)), NA)
# [1] NA  1 NA  2  2 NA  3 NA NA  4  4 NA

説明:

  • xは がどこにあるかを示す TRUE/FALSE のベクトルSpanです4
  • tail(x, -1)安全な書き方ですx[2:length(x)]
  • head(x, -1)安全な書き方ですx[1:(length(x)-1)]
  • tail(x, -1) - head(x, -1) == 1Span != 4からに移動した場所を示す TRUE/FALSE のベクトルですSpan == 4
  • 上記のベクトルは よりも 1 要素短いためx、その前に追加head(x, 1)しました。head(x, 1)は安全な書き方x[1]です。
  • 次にcumsum、ベクトル TRUE/FALSE を増加する整数のベクトルに変換します。そこSpanからのジャンプは1 ずつ増加!=4==4、それ以外の場合は一定のままです。
  • すべてが にラップされるため、TRUE の場合、つまりifelsewhere の数値のみが表示されます。 xSpan == 4
于 2012-10-20T01:37:26.483 に答える
1

rleと を使用した別の方法を次に示しrepます。あなたのdata.frame名前が「test」であると仮定します。

まず、「Sequence」列を初期化し、NA.

test$Sequence <- NA

次に、一致させる条件を指定します。この場合はtest$Span == 4.

x <- test$Span == 4

rle3 番目に、の出力 (lengthsと) の組み合わせを使用してvalues、シーケンス内の新しい実行がそれぞれ何回発生するかを取得します。

spanSeq <- rle(x)$lengths[rle(x)$values == TRUE]

最後にrep、引数をステップ 3 で取得した結果に設定して使用します。 で一致するインデックスに従ってtimesの必要な値をサブセット化し、それらを新しいシーケンスに置き換えます。test$Sequencetest$Span == 4

test$Sequence[x] <- rep(seq_along(spanSeq), times = spanSeq)
test
#    ID    X    Y  Time Span Sequence
# 1   1 3445 7671  0:00    -       NA
# 2   2 3312 7677  4:00    4        1
# 3   3 3309 7680 12:00    8       NA
# 4   4 3299 7681 16:00    4        2
# 5   5 3243 7655 20:00    4        2
# 6   6 3222 7612  4:00    8       NA
# 7   7 3260 7633  0:00    4        3
# 8   8 3254 7641  8:00    8       NA
# 9   9 3230 7612  0:00   16       NA
# 10 10 3203 7656  4:00    4        4
# 11 11 3202 7678  8:00    4        4
# 12 12 3159 7609 20:00   12       NA

関連する手順を理解したら、 で直接これを行うこともできますwithin()。以下は同じ結果になります。

within(test, {
  Sequence <- NA
  spanSeq <- rle(Span == 4)$lengths[rle(Span == 4)$values == TRUE]
  Sequence[Span == 4] <- rep(seq_along(spanSeq), times = spanSeq)
  rm(spanSeq)
})
于 2012-10-20T06:28:01.493 に答える
0
count = 0
for (i in 1:max(ID)) {
      Sequence[i] = ifelse(Span[i] <= 4, count <- count+1, NA)
}
于 2012-10-20T01:10:16.057 に答える