Determining the distance between locations or between locations and respective habitat types can serve a variety of purposes. Several resource selection procedures require a description of the daily movement distance of an animal to determine the habitat available to an animal or when generating random locations around known locations. We will start here with a method to determine the average distance moved by mule deer in Colorado in a study to determine methods to alleviate depradation on sunflowers that have become a high commodity crop in the area.

  1. Exercise 3.3 - Download and extract zip folder into your preferred location
  2. Set working directory to the extracted folder in R under File - Change dir...
  3. First we need to load the packages needed for the exercise

    library(adehabitatLT)
    library(chron)
    library(class)
    library(Rcmdr)
  4. Now open the script "DistanceUniqueBurst.R" and run code directly from the script

    muleys <-read.csv("DCmuleysedited.csv", header=T)
    str(muleys)
  5. Code to subset dataset for an individual animal

    muley15 <- subset(muleys, id=="D15")
    str(muley15)
    summary <- table(muley15$UTM_Zone,muley15$id)
    summary
    muley15$id <- factor(muley15$id)

    #Sort data to address error in code and then look at first 10 records of data to confirm

    muley15 <- muley15[order(muley15$GPSFixTime),]
    muley15[1:10,]#code displays the first 20 records
  6. Prepare data to create trajectories using the ltraj command in Adehabitat LT

    ####################################################
    #Example of a trajectory of type II (time recorded) with conversion of the date to the format #POSIX needs to be done to get proper digits of date into R then POSIXct uses #library(chron)
    da <- as.character(muley15$GPSFixTime)
    da <- as.POSIXct(strptime(muley15$GPSFixTime,format="%Y.%m.%d %H:%M:%S"))
    head(da)

    #Attach da to muley15
    muley15$da <- da

    #Creates a column of time difference between each location
    timediff <- diff(muley15$da)
    muley15 <-muley15[-1,]
    muley15$timediff <-as.numeric(abs(timediff))
    str(muley15)

    #Clean up muley15 for outliers
    newmuleys <-subset(muley15, muley15$X > 599000 & muley15$X < 705000 & muley15$Y > 4167000 & muley15$timediff < 14401)
    muley15 <- newmuleys
  7. Create a spatial data frame of locations for muley 15 for use in creating trajectories that includes time difference between locations and dates in proper format (as.POSIXct)

    data.xy = muley15[c("X","Y")]
    #Creates class Spatial Points for all locations
    xysp <- SpatialPoints(data.xy)
    #proj4string(xysp) <- CRS("+proj=utm +zone=12 +ellps=WGS84")
    #Creates a Spatial Data Frame from
    sppt<-data.frame(xysp)

    #Creates a spatial data frame of ID
    idsp<-data.frame(muley15[2])
    #Creates a spatial data frame of dt
    dtsp<-data.frame(muley15[24])
    #Creates a spatial data frame of Burst
    busp<-data.frame(muley15[23])
    #Merges ID and Date into the same spatial data frame
    merge<-data.frame(idsp,dtsp,busp)
    #Adds ID and Date data frame with locations data frame
    coordinates(merge)<-sppt
    plot(merge)
    str(merge)
  8. Creation of an object of class "ltraj" for muley15 dataset

    ltraj <- as.ltraj(coordinates(merge),merge$da,id=merge$id)
    plot(ltraj)
    ltraj

    #CAN BE USED TO REMOVE TIME FROM DATE IN GPSFIXTIME COLUMN if needed
    #Date <- as.character(muleys$GPSFixTime)
    #Date <- as.POSIXct(strptime(muleys$GPSFixTime,"%Y.%m.%d"))
    #muleys$Date <- Date
    #str(muleys)
  9. Need to create separate "bursts" for each trajectory based on the number of locations collected each day. In our case it was 8 (i.e., locations collected every 3 hours during a 24-hour period).

    ## We want to study the trajectory of the day at the scale
    ## of the day. We define one trajectory per day. The trajectory should begin
    ## at 22H00
    ## The following function returns TRUE if the date is comprised between
    ## 06H00 and 23H00 (i.e. results in 3 locations/day bursts)
    foo <- function(date) {
    da <- as.POSIXlt(date)
    ho <- da$hour + da$min
    return(ho>15.9&ho<23.9)
    }
    deer <- cutltraj(ltraj, "foo(date)", nextr = TRUE)

    #Notice that the above code will remove 345 relocations that fall
    #outside of your time criteria
    #Warning message:
    #In cutltraj(ltraj, "foo(date)", nextr = TRUE) :
    # At least 3 relocations are needed for a burst
    #345 relocations have been deleted

    deer

    #Shows results of cutting the traj into individual bursts
    #NOTE the "Irregular traject" line below because we will revisit this later!
    #*********** List of class ltraj ***********
    #Type of the traject: Type II (time recorded)
    #Irregular traject. Variable time lag between two locs

    #Characteristics of the bursts:

    #idburstnb.relocNAsdate.begindate.end
    1 D15 D15.001 6 0 2011-10-12 03:00:52 2011-10-12 18:00:52
    2 D15 D15.003 7 0 2011-10-13 00:00:35 2011-10-13 18:00:35
    3 D15 D15.005 7 0 2011-10-14 00:00:42 2011-10-14 18:00:42
    4 D15 D15.007 7 0 2011-10-15 00:00:35 2011-10-15 18:00:45
    5 D15 D15.001 7 0 2011-10-16 00:00:39 2011-10-16 18:00:49
    6 D15 D15.001 6 0 2011-10-17 00:01:07 2011-10-17 15:01:03
    7 D15 D15.001 7 0 2011-10-18 00:00:34 2011-10-18 18:00:48
    8 D15 D15.001 7 0 2011-10-19 00:00:36 2011-10-19 18:00:40
    9 D15 D15.001 7 0 2011-10-20 00:00:53 2011-10-20 18:00:40
    10 D15 D15.001 7 0 2011-10-21 00:00:39 2011-10-21 18:00:37
  10. Code to change ltraj to a data.frame to summarize distance between locations for each daily burst

    head(deer)
    dfdeer <- ld(deer)
    head(dfdeer)
    str(dfdeer)

    str(dfdeer)
    'data.frame': 2243 obs. of 13 variables:
    $ x : num 677932 679037 679429 679750 679453 ...
    $ y : num 4189551 4189493 4189406 4189053 4188461 ...
    $ date : POSIXct, format: "2011-10-12 03:00:52" "2011-10-12 06:00:52"
    $ dx : num 1105 392 321 -297 163 ...
    $ dy : num -58 -87 -353 -592 -89 NA -189 756 395 95 ...
    $ dist : num 1107 402 477 662 186 ...
    $ dt : num 10800 10786 10796 10808 10810 ...
    $ R2n : num 0 1224389 2262034 3553128 3501541 ...
    $ abs.angle: num -0.0524 -0.2184 -0.8328 -2.0358 -0.4998 ...
    $ rel.angle: num NA -0.166 -0.614 -1.203 1.536 ...
    $ id : Factor w/ 1 level "D15": 1 1 1 1 1 1 1 1 1 1 ...
    $ burst : Factor w/ 325 levels "D15.001","D15.003",..: 1 1 1 1 1 1 2 ...
    $ pkey : Factor w/ 2588 levels "D15.2011-10-12 03:00:52",..: 1

    #Code to get mean distance moved for each burst
    summary <- numSummary(dfdeer[,"dist"],groups=dfdeer$burst, statistics=c("mean","sd"))
    summary

    #Convert matrix from data.frame to a matrix to export as a .csv file
    mean <- as.matrix(summary$table)

    #Write.table gives csv output of Summary. Be sure to specify the directory and the output files will be stored there
    write.table(mean, file = "Distance.csv", sep =",", row.names = TRUE, col.names = TRUE, qmethod ="double")