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...
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 ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With