2015-02-24 30 views
0

簡而言之,我試圖矢量化我的data.table代碼並刪除2 for循環。具體而言,我比較兩個不同的行,並不知道如何矢量化我的代碼。以下是詳細信息:當跨多行比較時矢量化循環與data.table

我想要計算魚在給定魚的座標的情況下移過一條線的次數。我只關心單向移動(例如,從北到南但不是從南到北)。實際數據是二維的,有成千上萬的觀測數據。我創建了一個一維,可重現的例子。

我查看了data.tableFAQ並通過SO搜索使用"vectorize data.table"。如果我不是「問正確的問題」(即用正確的術語搜索),我會適當地指出我應該尋找什麼來解決我的問題。

這裏是我的榜樣,就是我目前在做:

library(data.table) 
dt = data.table(
    fish = rep(c("a", "b"), each = 4), 
    time = rep(c(1:4), 2), 
    location = c(1, 1, 2, 2, 1, 1, 1, 1)) 

crossLine = 1.5 # Coordinates that I care about 
dt[ , Cross := 0] ## did the fish cross the line during the previous time step? 

fishes = dt[ , unique(fish)] 

for(fishIndex in fishes){ # loop through each fish 
    sampleTime = dt[ fishIndex == fish, time] 
    nObs = length(sampleTime) 
    ## In the real dataset, the no. of observations varies by fish 
    for(timeIndex in 1:(nObs - 1)){ #loop through each time point 
     if(dt[ fishIndex  == fish & sampleTime[timeIndex] == time, 
      location <= crossLine] & 
     dt[ fishIndex  == fish & sampleTime[timeIndex + 1] == time, 
      location > crossLine] 
     ){dt[ fishIndex == fish & time == sampleTime[timeIndex + 1], 
       Cross := 1] # record if the fish crossed the line 
      } 
     } 
} 

我的理想的解決方案看起來像這樣:

moveCheck <- Vectorize(function(...)) 
dt[ , Cross := moveCheck(location, fish)] 

fish是函數內部,以確保我不意外記錄在魚類之間轉換時的運動。

所以,在這裏我的問題:什麼是使用data.table語法來提高此代碼的性能和刪除循環的方法?

回答

4

這是否適用於您(它適用於OP示例,但我不確定這是多麼具有代表性)?

dt[, cross := c(0, diff(location >= crossLine) > 0), by = fish] 
+0

感謝您的快速回復。它似乎工作,但我將無法檢查,直到午餐後。在完整的數據集中仔細檢查後,我會接受您的答案。另外,感謝您向我展示'diff'功能! – 2015-02-24 17:47:32