2013-10-29 16 views
3

我試圖在RMark之內創建(在R中)使用歷史記錄;即如果遭遇已經發生,則返回「1」,如果沒有發生,返回「0」。計算標記重獲模型的遭遇歷史

的樣本數據:

zm <- structure(list(date.time = structure(c(1365905306, 1365919237, 
1365923863, 1365929487, 1365931725, 1365942003, 1365945361, 1366143204, 
1366159355, 1366159863, 1366164285, 1366202496, 1366224357, 1366238428, 
1366243685, 1366250254, 1366252570, 1366314236, 1366315282, 1366386242 
), class = c("POSIXct", "POSIXt"), tzone = ""), station = c("M1", 
"M2", "M2", "M3", "M4", "M3", "M4", "M7", "L1", "M1", "M2", "M2", 
"L4", "M2", "M2", "M3", "M4", "M1", "M2", "M1"), code = c(10908, 
10908, 10897, 10908, 10908, 10897, 10897, 10908, 10908, 10914, 
10914, 10916, 10908, 10917, 10910, 10917, 10917, 10913, 10913, 
10896)), .Names = c("date.time", "station", "code"), row.names = c(5349L, 
51L, 60L, 7168L, 65L, 7178L, 70L, 6968L, 8647L, 5362L, 79L, 94L, 
9027L, 96L, 105L, 7200L, 114L, 5382L, 123L, 5388L), class = "data.frame") 

可能遭遇歷史(站,以檢查是否發生或不遭遇):

rec<- c("M1", "M2","M3","M4","M5","M6","M7") 

什麼是重要的是,遭遇歷史輸出指的rec順序以上。

因此,對於每一個code我想看看它在第一站檢測,即"M1"如果是這樣,然後返回一個「1」,然後看它是否是在第二站"M2"檢測,如果沒有返回一個「0 「;這最終會以0和1的字符串結尾。

我能夠得到的數據是在rec通過:

library("plyr") 
zm2 <- ddply(zm, c("code"), function(df) 
data.frame(arrive=(df[which(df$station %in% rec),]))) 

但是我不確定如何在rec才能運行這個,然後返回一個「0」或「1」。

最後,我希望有一個data.frame輸出結構如下:

ch  code 
00101 1 
00011 2 

等等...

+1

也許'table'有幫助嗎? '表(zm $ code,zm $ station)' –

回答

2

table()確實去,通過paste0()遵循表摺疊成一個字符串的方法。 (感謝您的可重複的例子!)

rec <- sort(unique(zm$station)) 
cfun <- function(x) { 
    tab <- with(x,table(factor(station,levels=rec))) 
    data.frame(ch=paste0(as.numeric(tab),collapse="")) 
} 
library(plyr) 
ddply(zm,"code",cfun) 
## code  ch 
## 1 10896 0010000 
## 2 10897 0001110 
## 3 10908 1111111 
## 4 10910 0001000 
## 5 10913 0011000 
## 6 10914 0011000 
## 7 10916 0001000 
## 8 10917 0001110 

或者通過@alexis_laz的建議:

tab2 <- with(zm,table(code,station)) 
ctab <- apply(tab2,1,paste0,collapse="") 
data.frame(code=names(ctab),ch=ctab) 

(代碼列出兩次,一次作爲行名稱,一次爲一列)。 後者的版本可能會更快一些,如果你有一個非常大的數據集或需要做這個數千次...

+0

非常好,非常感謝! –

0

想到我會提供一個備用的解決方案來創建遇​​到的歷史,以防萬一你想交叉檢查的結果與不同的方法:

## Begin 
zm$code <- as.character(zm$code) 
tag.list = as.character(unique(zm$code)) # create a vector of all tags (codes) detected 
sta.list = as.character(unique(zm$station)) # make a vector of the station names 

# create empty data frame for filling encounter history later 
enc.hist = as.data.frame(matrix(rep(NA,(length(tag.list)*length(sta.list))), 
          length(tag.list), length(sta.list))) 
colnames(enc.hist) = sta.list 
rownames(enc.hist) = tag.list 

# fill in data frame using a for-loop: 
for (i in 1:length(sta.list)) 
{ 
    sub <- zm[zm$station == sta.list[i],] #subset datos down to just the station you're currently looping 
    subtags <- unique(sub$code) #creates vector of tags present at that station 
    enc.hist[,i] <- tag.list %in% subtags #fills in the column of enc.hist with True or False if that tag is seen or not 
} 
head(enc.hist) # you now have a matrix with TRUE (1)/FALSE (0) for encounters: 

M1 M2 M3 M4 M7 L1 L4 
10908 TRUE TRUE TRUE TRUE TRUE TRUE TRUE 
10897 FALSE TRUE TRUE TRUE FALSE FALSE FALSE 
10914 TRUE TRUE FALSE FALSE FALSE FALSE FALSE 
10916 FALSE TRUE FALSE FALSE FALSE FALSE FALSE 
10917 FALSE TRUE TRUE TRUE FALSE FALSE FALSE 
10910 FALSE TRUE FALSE FALSE FALSE FALSE FALSE 

## Finally, use logical syntax to convert TRUE to '1' and FALSE to '0' 
enc.hist[enc.hist==TRUE] <- 1 
enc.hist[enc.hist==FALSE] <- 0 
enc.hist 

     M1 M2 M3 M4 M7 L1 L4 
10908 1 1 1 1 1 1 1 
10897 0 1 1 1 0 0 0 
10914 1 1 0 0 0 0 0 
10916 0 1 0 0 0 0 0 
10917 0 1 1 1 0 0 0 
10910 0 1 0 0 0 0 0 
10913 1 1 0 0 0 0 0 
10896 1 0 0 0 0 0 0 

現在你可以使用@ alexis_laz的優秀代碼上enc.hist用於摺疊成RMARK的.INP。

更詳細,但是提供了(希望)工程,以及並保留站秩序的另一種方法,雖然for循環,如果你有幾百萬的檢測肯定會減慢你的速度。