Calculating distances between individuals from xy coordinates

Viewed 91

I have a large dataset of xy coordinates for 48 individuals over 3 months. Coordinates have been automatically collected 0-10 times/minute for every individual but this varies.

I've been trying to find a way to calculate the distance between each individual and every other individual at each time point using code adapted from the link below, but even though my data structure is identical (animal ID, x, y, date/time) the output produced comes up as null(empty). I'm not sure what I'm doing wrong or if I'm missing something.

Faster way to calculate distance between all individuals during each time step

here is the code I was initially using:

library(data.table)

tag33 <- read.csv("data.csv")

ID <- tag33$ID
x <- tag33$x
y <- tag33$y
tagTimet <- as.POSIXct(tag33$date)

dt33 <- data.table(ID,x,y,tagTimet)

# distance
dist.between.animals <- function(ID1, x1, y1, ID2, x2, y2) {
  if (ID1 == ID2) return(NA)
  sqrt((x1 - x2)^2 + (y1 - y2)^2)
}

# Get unique collar id of each animal, create column name for all animals per animal
tag33_ids <- dt33[ , unique(ID)]
tag33_ids_str <- dt33[,paste0("dist_to_", unique(ID))]
datetimes <- dt33[ , unique(tagTimet)]

# Calculate distance of each animal to all animals, at same time
testdt <- for (i in 1:length(tag33_ids)) {
  for (j in 1:length(datetimes)) {
    x1 <- dt33[.(tag33_ids[i], datetimes[j]), x, on = .(ID, tagTimet)]
    y1 <- dt33[.(tag33_ids[i], datetimes[j]), y, on = .(ID, tagTimet)]
    dt33[tagTimet == datetimes[j], tag33_ids_str[i] := mapply(function(c, x2, y2) dist.between.animals(tag33_ids[i], x1, y1, c, x2, y2), ID, x, y)]
  }
}

I read the answers from the link and tried to implement the suggestions, resulting in this code:

animal_ids_str <- dt33[,paste0("dist_to_",sort(unique(ID)))]
# set keys
setkey(dt33,ID,tagTimet)
# add the distance columns
dt33[,(animal_ids_str):=as.double(NA)]

# custom function that computes animal distances for a subset of dt at the same date
distancesInSameDate <- function(subsetDT33,animal_ids_str){
  m <- as.matrix(dist(subsetDT33[,.(x,y)]))
  diag(m) <- NA
  cols <- paste0("dist_to_",subsetDT33$ID)
  missingCols <- animal_ids_str[is.na(match(animal_ids_str,cols))]
  m <- cbind(m,matrix(NA,nrow=nrow(m),ncol=length(missingCols)))
  colnames(m) <- c(cols,missingCols)
  DF <- as.data.frame(m,stringsAsFactors=F)
  DF <- DF[,match(animal_ids_str,colnames(DF))]
  return(DF)
}

# let's compute the distances
dt33[,(animal_ids_str):=distancesInSameDate(.SD,animal_ids_str),by=date] 

which results in the following message: "Error in as.vector(x, "list") : cannot coerce type 'closure' to vector of type 'list'"

I have no idea what I'm doing. please help.

0 Answers
Related