计算标记 - 重新捕获模型的遇到历史记录

时间:2013-10-29 12:47:11

标签: r sequence

我正在尝试创建(在R中)在RMark内使用的遭遇历史记录;即如果发生了遭遇,则返回" 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",如果是,那么返回&#39; 1&#39;,然后查看是否检测到它在第二站"M2"如果没有返回&#34; 0&#34 ;;这最终将以0和1的字符串结束。

我能够获取rec到的数据:

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

但是,我不确定如何按rec的顺序运行此操作,然后返回&#39; 0&#39;或者&#39; 1&#39;。

最终我想要一个data.frame输出结构如下:

ch       code
00101    1
00011    2

依旧......

2 个答案:

答案 0 :(得分: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)

(代码列出两次,一次作为行名,一次作为列)。 后一个版本可能会快一点,如果你有一个非常大的数据集或需要这样做数千次......

答案 1 :(得分: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循环肯定会减慢你的速度。