2016-04-28 22 views
1

現在のdata.tableをループでサブセット化しようとしています。プロセスは非常に遅いです。サブセット化する前のデータサンプルを示します。data.tableファイルでより効率的なループを作成

#  V1 V2  V3  type 
#1: 1 362.25 361.75 A 
#2: 1 362.25 361.75 B 
#3: 3 362.25 361.75 C 
#4: 4 362.75 362.00 C 
#5: 8 362.50 362.00 A 
#6: 6 362.50 362.00 B 
#7: 12 362.50 362.89 A 
#8: 8 362.25 362.05 B 
#9: 9 362.25 362.00 A 
#10: 17 362.25 362.20 B 
#11: 29 362.25 362.90 C 
#12: 41 362.25 362.40 C 
#13: 99 362.25 362.10 C 
#14: 81 362.25 362.00 C 

変数 "type"に基づいてデータをサブセット化する必要があります。私はすべての行を(​​)にしたいだけで、(data$type="C")行が続く場合にのみ、(data$type =="A")と(data$type =="B")の2つの行が必要です。 (data$type == "C")場合は、その行は維持する必要が

#  V1 V2  V3  type 
#1: 1 362.25 361.75 A 
#2: 1 362.25 361.75 B 
#3: 3 362.25 361.75 C 
#4: 4 362.75 362.00 C 
#9: 9 362.25 362.00 A 
#10: 17 362.25 362.20 B 
#11: 29 362.25 362.90 C 
#12: 41 362.25 362.40 C 
#13: 99 362.25 362.10 C 
#14: 81 362.25 362.00 C 

:サブセット化した後、データは次のようになります。行番号1、#2、#9、#10も、"type==C"行の後に続くため、保持されます。

私は今、ループを使用していますが、非常に遅いです。

data$temp<-"omit" 
    for (j in 3:nrow(data)){ 
    if (data$type[j] == "C" && data$type[j-1] == "B" 
     && data$type[j-2] == "A") 
    { 
     data$temp[j] <- "pair" ; data$temp[j-1] <- "pair"; data$temp[j-2] <- "pair" 
    } 
    } 



    for (j in 2:nrow(data)){ 
    if (data$type[j-1] == "C" && data$type[j] == "C" 
     && data$temp[j-1] == "pair" && data$temp[j]== "omit") 
    { 
     nearby$temp[j] <- "pair" 
    } 
    } 

data<-data[!(data$temp=="omit"),] 

このコードは問題なく機能しますが、遅すぎます。効率を向上させるためのアイデアを教えてください。同じ仕事をしてください。

は、あなたが「C」を持っている行のインデックスを取得するために whichを使用することができます

+0

ドンしてください(ABが提示された順序で常にあると仮定して)次のようにdata.tableshift -functionを使用すると、あなたのデータをサブセットすることができますあなたのコードをhtmlやjavascriptとしてマークする行を追加しないでください。それはディスプレイを台無しにする。 – Frank

+0

提案のおかげで@フランク – jester

答えて

3

この場合、for -loopの必要はありません。

DT[type=='C' | (type=='A' & shift(type, 2, NA, 'lead')=='C') | (type=='B' & shift(type, 1, NA, 'lead')=='C')] 

与える:

V1  V2  V3 type 
1: 1 362.25 361.75 A 
2: 1 362.25 361.75 B 
3: 3 362.25 361.75 C 
4: 4 362.75 362.00 C 
5: 9 362.25 362.00 A 
6: 17 362.25 362.20 B 
7: 29 362.25 362.90 C 
8: 41 362.25 362.40 C 
9: 99 362.25 362.10 C 
10: 81 362.25 362.00 C 
+0

これは良いと速かった – jester

1

そんなにありがとう。次に、見つけられた数より少ない数のインデックス1と2を含めます。例えば

[1] 3 4 9 10 

をあなたもやる次に行1、2、7、8 を含める:

df = data.frame(d = c(1,2,3,4,5,6,7,8,9,0),t = c("A","B","C","C","A","B","A","B","C","C")) 
> df 
    d t 
1 1 A 
2 2 B 
3 3 C 
4 4 C 
5 5 A 
6 6 B 
7 7 A 
8 8 B 
9 9 C 
10 0 C 

c(which(df$t=="C")が返されます

df[sort(unique(c(which(df$t=="C"),which(df$t=="C")-1,which(df$t=="C")-2))),] 

    d t 
1 1 A 
2 2 B 
3 3 C 
4 4 C 
7 7 A 
8 8 B 
9 9 C 
10 0 C 

sortuniqueはリピートを削除します並べ替え順にすべてのインデックスを設定します。

注:私はCACやCBCのようなシーケンスがないと仮定しています。これには、BACCのようなシーケンスも含まれます(AとBの順序はチェックされません)。

+0

あなたはシーケンスについて正しいです。コードはうまくいった。ありがとう – jester