Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calculate encounter history for mark-recapture models

Tags:

r

sequence

I am trying to create (in R) an encounter history for use within RMark; i.e. if an encounter has occurred return a "1" and if the encounter did not occur return a "0".

Sample data:

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")

Possible encounter history (stations to check if encounter occurred or not):

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

What is important is that the encounter history output refers to the order of rec above.

So for each code I want to see if it was detected at the first station i.e. "M1" and if so then return a '1', then see if it was detected at the second station "M2" and if not return a "0"; this will ultimately end up as a character string of 0's and 1's.

I am able to get data which is in rec through:

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

However I am unsure how to run this in order of rec and then to return either a '0' or '1'.

Ultimately I want a data.frame output structure follows:

ch       code
00101    1
00011    2

and so on...

like image 601
Salmo salar Avatar asked Dec 06 '25 03:12

Salmo salar


1 Answers

table() is indeed the way to go, follow by paste0() to collapse the table into a string. (Thanks for the reproducible example!)

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

Or as suggested by @alexis_laz:

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

(the code is listed twice, once as a row name and once as a column). The latter version is probably a bit faster, in case you have a really large data set or need to do this thousands of times ...

like image 127
Ben Bolker Avatar answered Dec 07 '25 17:12

Ben Bolker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!