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.
- Exercise 3.3 - Download and extract zip folder into your preferred location
- Set working directory to the extracted folder in R under File - Change dir...
- First we need to load the packages needed for the exercise
library(adehabitatLT)
library(chron)
library(class)
library(Rcmdr) - Now open the script "DistanceUniqueBurst.R" and run code directly from the script
muleys <-read.csv("DCmuleysedited.csv", header=T)
str(muleys) - 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 - 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 - 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) - 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) - 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:
# id burst nb.reloc NAs date.begin date.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 - 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")