2016-05-13 8 views
1

私は不規則な日付の列を持つデータセットを持っています。私はインデックスの列を作成したい。インデックスID(例えば、1)は、3つの異なる連続した日付の間で同じであり、その後、次の3つの異なる連続する日付のために(例えば2に)変化する。カスタマイズされたインデックスカラム

structure(list(Date = c(42370, 42371, 42371, 42371, 42372, 42372, 
42375, 42375, 42375, 42377, 42377, 42383, 42383, 42385, 42386, 
42386, 42386, 42393, 42393, 42394, 42394, 42395, 42398, 42398, 
42398, 42398), Index = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 
2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4)), .Names = c("Date", 
"Index"), row.names = c(NA, 26L), class = "data.frame") 
+0

質問は奇妙に見えるかもしれませんが、私のプロジェクトにとっては非常に重要です。 –

+0

[良い質問をする方法](http://stackoverflow.com/help/how-to-ask)と[再現可能な例を与える方法](http://stackoverflow.com/questions)の情報をお読みください。/5963269/how-to-make-a-great-r-reproducible-example/5963610を参照)。これは他の人があなたを助けることをはるかに容易にします。 – Jaap

+0

今はいいですか?私は日付の列と希望の列(インデックス)のファイルを添付しました。コードに関しては、私は手がかりがありません。 –

答えて

3

これは、Dateの一意の値に対してグループ化された3つのインデックスを作成し、文字名を使用して変換のルックアップテーブルを管理します。

fac <- ((seq(length(unique(dat$Date)))-1) %/%3) +1 
names(fac) <- unique(dat$Date) 

dat$myIndex <- fac[as.character(dat$Date)] 
dat 
#------- 
    Date Index myIndex 
1 42370  1  1 
2 42371  1  1 
3 42371  1  1 
4 42371  1  1 
5 42372  1  1 
6 42372  1  1 
7 42375  2  2 
8 42375  2  2 
9 42375  2  2 
10 42377  2  2 
11 42377  2  2 
12 42383  2  2 
13 42383  2  2 
14 42385  3  3 
15 42386  3  3 
16 42386  3  3 
17 42386  3  3 
18 42393  3  3 
19 42393  3  3 
20 42394  4  4 
21 42394  4  4 
22 42395  4  4 
23 42398  4  4 
24 42398  4  4 
25 42398  4  4 
26 42398  4  4 
+0

ありがとう!コードの仕組みを説明してください。 –

+0

整数ベースのシーケンスを1ベースではなくゼロベースにシフトし、モジュロ除算 '%/%'を使用して、その結果に1を戻して、グループ化ベクトルを1から始めるようにします。 2を1を引くよりもむしろ2番目のステップを必要としませんでした。 –

+0

このステップが行っていること:names(fac)< - unique(dat $ Date)? –

4

data.tableパッケージとcumsumからrleidを使用する:ここでは、日付のサンプルとどのように目的の列が見えるものである

library(data.table) 
setDT(d1)[, index := (rleid(Date)-1) %% 3 
      ][, index := cumsum(index < shift(index, fill=1))][] 

が与える:

 Date index 
1: 01-01-16  1 
2: 02-01-16  1 
3: 02-01-16  1 
4: 02-01-16  1 
5: 03-01-16  1 
6: 03-01-16  1 
7: 06-01-16  2 
8: 06-01-16  2 
9: 06-01-16  2 
10: 08-01-16  2 
11: 08-01-16  2 
12: 14-01-16  2 
13: 14-01-16  2 
14: 16-01-16  3 
15: 17-01-16  3 
16: 17-01-16  3 
17: 17-01-16  3 
18: 24-01-16  3 
19: 24-01-16  3 
20: 25-01-16  4 
21: 25-01-16  4 
22: 26-01-16  4 
23: 29-01-16  4 
24: 29-01-16  4 
25: 29-01-16  4 
26: 29-01-16  4 

説明を

  • rleid関数は、ランレングスIDを作成します。つまり、Dateが変更されるたびに、ランレングスIDは1だけ増加します。ランレングスIDから1をsubstracting、あなたが01 & 2年代のシーケンスのベクトルを取得し、それの弾性率(%% 3部分)を取ることによって
  • 最後のステップとして、前回の値との値の比較の累積合計を取得します。 index < shift(index, fill=1)TRUEの場合、cumsum関数はそれを1としてカウントします。

良好各ステップの変数を作成し、次のコードの出力を参照して、このコードが何を見るために:

setDT(d1)[, index1 := (rleid(Date)-1) %% 3 
      ][, index2 := cumsum(index1 < shift(index1, fill=1))][] 

使用するデータ:

d1 <- structure(list(Date = structure(c(16801, 16802, 16802, 16802, 16803, 16803, 16806, 
             16806, 16806, 16808, 16808, 16814, 16814, 16816, 
             16817, 16817, 16817, 16824, 16824, 16825, 16825, 
             16826, 16829, 16829, 16829, 16829), class = "Date")), 
       .Names = "Date", row.names = c(NA, 26L), class = "data.frame") 
+0

非常に良い!コードの進行状況を説明してください(私はまだ初心者レベルです) –

+1

@PolarBear私は解説を更新しました.HHH – Jaap

3

基地R.我々は、値のグループトリオにオブジェクトのrle(ランレングス符号化)を変更することができる:

DF$index = with(rle(DF$Date), { 
    g = ceiling(seq_along(values)/3) 
    split(values, g) <- seq(tail(g,1)) 
    inverse.rle(list(lengths = lengths, values = values)) 
}) 

奇妙0​​ビットaveから借用しました。 Date列が増加している場合、これは、より簡単に(@Jaapのおかげで)行うことができます。

DF$index = ceiling(match(DF$Date, unique(DF$Date))/3) # or... 
DF$index = ceiling(as.integer(factor(DF$Date))/3) 

data.table。データ。

library(data.table) 
setDT(DF)[, index := ceiling(rleid(Date)/3)] 
2

が、私は質問の以前のバージョンからのデータを使用:テーブルアナログは簡単です

df <- data.frame(Date = c("01-01-16", "02-01-16", "02-01-16", "02-01-16", 
         "03-01-16", "03-01-16", "06-01-16", "06-01-16", "06-01-16", "08-01-16", 
         "08-01-16", "14-01-16", "14-01-16", "16-01-16", "17-01-16", "17-01-16", 
         "17-01-16", "24-01-16", "24-01-16", "25-01-16", "25-01-16", "26-01-16", 
         "29-01-16", "29-01-16", "29-01-16", "29-01-16"), 
        Index = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 
         3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L)) 
私が今までに、文字から日付列を変換し、データフレームであることを確認することによって開始する

日付順に並べ替えられます(Dateが既に数値でデータの新しいバージョンでその部分を必要としない、とあなたは確信している場合、データフレームはすでに日付でソートされている):

df$Date <- as.Date(df$Date, format="%d-%m-%y") 
df <- df[ order(df$Date),] 
df$ndx <- c(factor(as.numeric(df$Date))) 
df$ndx <- cut(df$ndx, seq(0.5, max(df$ndx)+0.5, by=3), labels=FALSE) 
:それは等間隔で、その後 cut - (ここで私はそれを行うための速記として cを使用)、それを行うための一つの方法は、考慮して、unclassに変換することである -それから私は、連続する整数に日付を変換します
関連する問題