R/MakeTrip.R

Defines functions MakeTrip

Documented in MakeTrip

#' MakeTrip Function to make a TripNum variable
#'
#' The objective of this function to to partition tracking data into "trips"
#' based on begining and returning to a fixed location.  It was designed for use
#' with GPS tracking data from seabirds that during the breeding season are
#' central place foragers, leaving from colony sites on food finding trips and
#' returning to the colony afterward.  This function relies on a column with a
#' disntance in km from each point along the track to the colony and a distance
#' cutoff.  It numbers each trip starting with the first point beyond the
#' distance cutoff and ending with the last point beyond the cutoff with a
#' sequential number starting with 1.  All points inside the cutoff are labled
#' 0.  In the future it could be nice to have these labeled with sequetial
#' numbers as well.
#'
#' @author Abram B. Fleishman \email{abram@@conservationmetrics.com}
#' @param tracks data.frame of data that you want to parse into trips
#' @param ID quoted name of column in data that is a unique key to individual
#'   bird_tag_deployment combos. This is the File from the GypsyLocRead output
#' @param DistCutOff Distance in km to use as a cut off radius around the colony
#'   to use to split the trips
#' @param Dist2Colony quoted name of column in data that has the distance in km
#'   from each point to the colony
#' @param NumLocCut Minimum number of points to consider in a trip
#' @return A new data frame with all original data plus two new columns: TripNum
#'   (consecutive trip number 0 = at colony) and ColonyMovement (in/out colony
#'   movements)
#' @importFrom dplyr lead bind_rows
#' @export

MakeTrip<-function(tracks,
                   ID="File",
                   DistCutOff=10,
                   Dist2Colony="Dist2Colony",
                   NumLocCut=3){

  Birds<-unique(tracks[[ID]])

  dataOut<-NULL
  for(j in 1:length(Birds)){

    # Subset for each bird
    BirdSub<-tracks[tracks[[ID]]==Birds[j],]
    BirdSub$InColony<-NULL

    # Print bird number
    print(paste(ID,Birds[j]))

    # If distance to colony is less than DistCutOff m make it a 0 else make it a 1
    # 0 =  in colony 1 = on trip
    BirdSub$InColony<-ifelse(BirdSub[[Dist2Colony]] < DistCutOff|is.na(BirdSub[[Dist2Colony]]),0,1)

    # offset by one (drop first record) Detect state change for "out" events
    # else NA
    # if the current ooint is in the colony but the next point is out of
    # the colony label it an "out"
    BirdSub$ColonyMovement<-ifelse(BirdSub$InColony == 0 & lead(BirdSub$InColony) == 1, "Out", NA)

    # Detect state change for "In" events else "out" or NA
    # if the current ooint is out of the colony but the next point is in
    # the colony label it an "in"
    BirdSub$ColonyMovement<-ifelse(BirdSub$InColony == 1 & lead(BirdSub$InColony) == 0, "In", BirdSub$ColonyMovement)

    # Get indicies of out events
    Out<-grep("Out", x = BirdSub$ColonyMovement)

    # If there is an "in" event get the indicies of the in events
    # else make the 2nd to last point an in event
    if ("In" %in% BirdSub$ColonyMovement ) {
      In<-grep("In", x = BirdSub$ColonyMovement)
    } else {
      In<-length(BirdSub$ColonyMovement)-1
    }

    # if the first "in" comes after the first "out" than make first index an "out"
    if(In[1]<Out[1]|length(Out)==0)  Out<-c(1,Out)

    #  if the last out is a larger index than the last in make the last event an "in"
    if(Out[length(Out)]>In[length(In)]) In<-c(In,nrow(BirdSub)-1)

    # add 1 to all the indecies in "in" so that they are the first point at colony
    In<-In+1

    # get the indeces of the ins and outs that have more than NumLocCut points
    sel<-which(abs(In-Out)>NumLocCut)

    #Trims trips that are shorter than a given number of locations, set to 0 to omit
    In<-In[sel]
    Out<-Out[sel]

    # add a vector of NAs to BirdSub that will be populated with trip numbers
    BirdSub$TripNum<-NA

    # add a tripnumber "i" to all the events between the ith out and ith in
    if(length(In)==0){
      warning(paste(ID,":", Birds[j], "did not make any trips. If this is an error, reduce DistCutOff or NumLocCut.\n",
                    ID,":", Birds[j],"has fewer then NumLocCut=",NumLocCut,"points within DistCutOff=", DistCutOff,"."))
    }else{
      for(i in 1:length(Out)){
        BirdSub$TripNum[Out[i]:In[i]]<-i
      }
    }

    dataOut<-bind_rows(dataOut,BirdSub)
  }

  # if not on a trip (within distance to colony threshold) than give a 0
  dataOut$TripNum[is.na(dataOut$TripNum)]<-0

  return(dataOut[ , -which(names(dataOut) =="InColony")])
}
abfleishman/trakR documentation built on Nov. 21, 2022, 7:59 a.m.