2016-04-28 59 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 

我想基於變量「類型」的數據子集。我只想保留所有行(​​),並且只有在後面跟着(data$type="C")行時,我也需要兩行(data$type =="A")和(data$type =="B")。子集後,數據應該是這樣的:

#  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 

如果(data$type == "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"),] 

此代碼工作正常,但速度太慢。請給我一些想法來提高效率,但做同樣的工作。

謝謝你這麼多

+0

請不要不要添加將您的代碼標記爲html或javascript的行;它弄亂了顯示器。 – Frank

+0

感謝您的建議@弗蘭克 – jester

回答

3

這種情況下不需要for -loop。隨着使用的data.tableshift功能全,你可以子集數據如下(假設AB總是在呈現順序):

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

您可以使用which,以獲得具有「C」的行的索引。然後包括索引1和2的數字比找到的少。

例如:

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")將返回:

[1] 3 4 9 10 

,但你也希望包括行1,2,7和8 然後做:

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