我有幾個月的數據文件,每個數據文件包含24個小時的魚x,y,z座標,記錄在兩個25x25x20m魚場圍欄中,用於40個標記的魚,每個標記每6-9秒定位一次。每個文件包含大約365,000個觀察值。如何從點數據計算區域的覆蓋範圍?
我想計算每天魚所覆蓋的筆的比例。我已經寫了一些R代碼來完成這項工作,但由於文件很大,運行大約需要4個小時。這是我的代碼:
xmin <- 8
ymin <- 11.5
xmax <- 33
ymax <- 36.5
boxsize <- 1
# define coverage grid
cov.grid <- matrix(c(xmin,ymin), nrow = 1, ncol = 2, byrow = FALSE)
colnames(cov.grid) <- c('x','y')
x <- xmin
y <- ymin
while(x < xmax)
{
while(y < ymax)
{
y <- y+boxsize
cov.grid <- rbind(cov.grid, c(x,y))
}
x <- x+boxsize
y <- ymin
cov.grid <- rbind(cov.grid, c(x,y))
}
cov.grid <- as.data.frame(cov.grid)
# count grid cells occupied by fish
day.row <- 1
grid.row <- 1
bin <- 0
cov.grid$occupied <- NA
for(grid.row in 1:nrow(cov.grid)){
x1 <- cov.grid[grid.row,1]
y1 <- cov.grid[grid.row,2]
x2 <- x1+boxsize
y2 <- cov.grid[grid.row+1,2]
repeat
{
if(dayfile[day.row,'PosX'] > x1 & dayfile[day.row,'PosX'] < x2 & dayfile[day.row,'PosY'] > y1 & dayfile[day.row,'PosY'] < y2) {bin <- 1} else {bin <- 0}
day.row <- day.row+1
if(bin == 1 | day.row == nrow(dayfile)){break}
}
cov.grid[grid.row,'occupied'] <- bin
day.row <- 1
}
# return coverage summary
coverage <- matrix(c(length(which(cov.grid$occupied == 1)), nrow(cov.grid), length(which(cov.grid$occupied == 1))/nrow(cov.grid)), ncol = 3)
colnames(coverage) <- c('occupied', 'total', 'proportion')
coverage
代碼的邏輯如下:
- 創建筆區域的矩陣網格。
- 對於每個網格單元,查看魚座標文件以檢查魚是否佔用該單元;如果是,則爲1,否則爲0。
- 在網格矩陣中添加一個新列以記錄每個單元是否被魚佔用。
- 計算佔用的單元格數量並計算筆的比例覆蓋率。
理想情況下,我希望網格分辨率爲0.1米分辨率,但即使是1米分辨率也需要4個小時才能運行; 25×25米的網格陣列= 625個單元,因此365,000條魚觀測的座標文件必須與網格陣列625次交叉製表。如果網格分辨率爲0.1米,那麼365,000個觀測值需要交叉列表625,000次,這可能需要幾周時間!
我確定必須有一個更有效的方法來做到這一點。然而,我現在只學了幾個月的R,所以我不知道如何改進代碼。
任何幫助或建議將不勝感激!
你可以砍掉首先發現了你的searchspace的邊緣最南方,南方,東方和西方的點,並直接分配0以外的任何東西。此外,您可以從更加寬鬆的解決方案開始,然後僅針對1的區域(如果大方塊中沒有魚,那麼沒有理由檢查其小方塊)來優化分辨率。但更好的方法可能是翻轉你的過程:識別每個魚的座標,然後在網格中將它們繪製爲1。 – ddunn801