Page 1 of 1

Splitting and combining capture histories

PostPosted: Mon Jan 23, 2012 1:23 pm
by jlaake
I use the following kind of code routinely in R to go back and forth between a vector of capture history strings (ch) and a capture history matrix (chmat) and thought that some might find it useful. It differs when you can have non-numeric characters in the capture history string as with the multi-state models.

Code: Select all
# split a vector of capture histories into a matrix when they are all numeric
chmat=t(sapply(strsplit(ch,""),function(x)as.numeric(x)))
# split a vector of capture histories into a matrix when they are alpha-numeric (as in MS designs)
chmat=do.call("rbind",strsplit(ch,""))
# reverse process to take matrix and create vector of ch strings
ch=apply(chmat,1,paste,collapse="")

Re: Splitting and combining capture histories

PostPosted: Fri Feb 10, 2012 9:07 pm
by wchallen
I find myself doing the same thing, I have two slightly different functions that also deal allow you to keep covariate data with the capture histories.

Code: Select all
## DESCRIPTION:
##  An internal function used to expand RMark capture histories of type 'ch'
##  where a single column contains the capture history as a concatenated 
##  string. The expansion turns this single column  into a matrix with each
##  occasion occupying a single column.  Any covariates in the data frame
##  appear in columns after the history.  The columns containing the capture
##  history are named with the following convention: 't.#', where the '#'
##  indicates the sampling occasion.
##
##  The expansion is necessary if we wish to manipulate or summarize properties
##  of the history. 
##
##  Possible manipulations include collapsing or expanding capture histories
##  (i.e. in the BPA analysis we can add 0's for years that have a missing
##  subarray line), getting raw detection counts by occasion, or determining
##  the first and last capture occasions of an individual.

ExpandCHdata <- function(ch, return.covariates=TRUE) {
  if (!any(colnames(ch) == 'ch'))
    stop('Not an RMark ch file')
  # split capture history
  split <- strsplit(ch$ch, "");
  x <- NULL
  for (i in split)
    x <- rbind(x, as.numeric(i))
  # Clean up the presentation of the expanded
  # capture history
  rownames(x) <- rownames(ch)
  colnames(x) <- paste('t', 1:ncol(x), sep='.')
 
  # Add the individual covariate data back
  if (return.covariates) {
    result <- cbind(x, ch[,-which(colnames(ch) == 'ch')])
  } else {
     result  <- x
  }
 
  # RETURN
  return(result)
}



Code: Select all
##  DESCRIPTION:
##    Collapse a matrix into RMark chdata type.  If you have covariate data
##    in the matrix as well (e.g. after the capture history) it is best to
##    use a column naming  convention of 't.1', 't.2', ... 't.T' for the capture
##    history. 
## 
## ARGUMENTS
##  ch.expand - a matrix representation of the capture history.  Column
##              names should be of the form 't.1', 't.2', ... 't.T', where T is the
##              total number of capture occasions
##  cols      - numeric vector indicating column #'s to use as the ch data. Needs to
##              be sepcified if columns are named with the 't.#' convention.  If
##              not specified

CollapseCHdata <- function(ch.expand, cols=NULL) {
  #
  # Convert to dataframe before manipulations.
  ch.expand <- data.frame(ch.expand)
 
  if (is.null(cols)) {
    ch.index <- grep('t\\.[0-9]+', colnames(ch.expand))
  } else {
     if (is.integer(cols)) {
       ch.index  <- cols
     } else {
      ch.index  <- NULL
       for (c in cols) {
        ch.index <- c(ch.index, which(colnames(ch.expand) == c))
       }
    }
  }   
  T <- length(ch.index)
  chdata <- cbind(
    as.character(apply(ch.expand[ ,ch.index], 1, paste, collapse="")),
    ch.expand[,-ch.index],
    stringsAsFactors = FALSE
   )
   colnames(chdata)[1] <- 'ch'
   return(chdata)
}


Re: Splitting and combining capture histories

PostPosted: Wed Feb 15, 2012 8:10 pm
by jlaake
Thanks for contributing the code. I'll look at what you wrote and maybe include it or something like it into the package so it is generally available.

--jeff