Implausible values from overlap()

91 views
Skip to first unread message

Jenny Hansen

unread,
Feb 23, 2024, 10:08:23 AM2/23/24
to ctmm R user group
Hi Chris,
  I was looking at the Bhattacharyya values from overlap and I am getting values that do not make sense. I get high BI values for individuals who do not have overlapping UDs. I have just started looking at the values for a single year and I have already found 2 cases out of four pairs. 

I'm attaching plots of the UDs of these individuals and here are the associated values:

W0425 and W0621:
low: 0.55
est: 0.8
high: 0.97

W0713 and W0818:
low: 0.41
est: 0.66
high: 0.88

Here is the code I am using to get the overlaps & values into a dataframe:

ol_2013 <- overlap(uds_2013)
low_matrix <- ol_2013$CI[,,1]
est_matrix <- ol_2013$CI[,,2]
high_matrix <- ol_2013$CI[,,3]

overlap_df <- data.frame(ID1 = character(),
                         ID2 = character(),
                         low = numeric(),
                         est = numeric(),
                         high = numeric(),
                         stringsAsFactors = FALSE)

individuals <- rownames(low_matrix)

for (i in 1:nrow(low_matrix)) {
  for (j in 1:ncol(low_matrix)) {
    if (i < j) { # This ensures that each pair is only considered once
      overlap_df <- rbind(overlap_df, data.frame(ID1 = individuals[i],
                                                 ID2 = individuals[j],
                                                 low = low_matrix[i, j],
                                                 est = est_matrix[i, j],
                                                 high = high_matrix[i, j]))
    }
  }
}

Is this a bug or am I doing something wrong here? I have tried getting the values directly from the matrix and they're the same, e.g.

> est_matrix["W0425_2013", "W0621_2013"]
[1] 0.8012772

Let me know if you need me to send data/scripts to verify.

Thanks,
Jenny
W0713_W0818_uds.png
W0425_W0621_uds.png

Christen Fleming

unread,
Feb 27, 2024, 8:52:40 PM2/27/24
to ctmm R user group
Hi Jenny,

The only time that I've seen this was when a user accidentally re-projected the data somewhere in the middle of the analysis.
If not, can you send me a copy of uds_2013?

Best,
Chris

Catherine Kelly

unread,
Oct 16, 2024, 2:32:20 AM10/16/24
to ctmm R user group
Hi guys,

Don't suppose you found a solve for this - I'm having a very similar problem with my UD's that have 0 overlap (they're about 10km apart...) but are saying a 0.82 (0.72-0.90) overlap.

Cheers :)
Cat

Christen Fleming

unread,
Oct 29, 2024, 11:35:24 PM10/29/24
to ctmm R user group
Hi Cat,

In that case the fit objects and UD objects were calculated in different projections.

In all cases I've seen it's been an issue of inconsistent projections. The data, fit objects, and UD objects have projection information that you can check with projection().

Best,
Chris

Lyn Brown

unread,
Dec 22, 2025, 2:09:03 AM (6 days ago) Dec 22
to ctmm R user group

Hi there,

I wanted to calculate the home range overlap for koalas. I was able to output a matrix of overlap values, which I thought where is supposed to be the BA coefficient ranging from zero to one period however, my values range from 0.08 to 21,000. This seems like it might be the raw area in squared meters that is shared between koalas. 21,0000 squared meters would be 2.1 hectares, which is reasonable for this species.

I'm not sure why I am getting this output when I specified the method in the overlap function as “Bhattacharyya”.

You'll see in my code, that I have overlap_matrix = overlap(AKDES_full),  but I had also tried overlap(AKDES_full, method = "Bhattacharyya"), which gave the same output.

As another potential fix, I tried  the code directly below this text, as per one of the help pages and a post by Allie Anderson.

AKDE_lst <- purrr::map2(tel, FITS,

            ~akde(.x, .y[[1]], #top model

                 grid = ref_grid))

 

overlap_matrix_1st = overlap(AKDES_1st)

 

However, I get the error message in this case that Error in `purrr::map2()`:

In index: 1.

With name: Abigail.

Caused by error in `akde()`:

! Data and models not in the same coordinate system.

 Even though, I have checked and my projection is the same for my telemetry object, list of fitted models, and utilization distributions, which I called “AKDES_full” in my code. I also formed a reference grid when calculating my AKDEs, and double checked that across all animals, the same reference grid and projection were used.

I followed working examples in this help group, specifically one posted by Allie Anderson  about creating a reference grid, and ensuring that I first project with my telemetry object, and then use that telemetry object to create the fitted models so they would all have the same projection.

I'm not sure how to extract the Bhattacharyya coefficients.

Any help is appreciated.

Minimal code is below. I can e-mail more detailed code if that is helpful.

######################FOR HR OVERLAP##################################

#1 Extract projection

PROJ <- ctmm::projection(tel[[1]])

 

#2 Force that projection onto ALL telemetry

tel <- lapply(tel, function(tel) {

  ctmm::projection(tel) <- PROJ

  tel

})

 

#3 then fit models

#TM

#parallel code for estimating fits

n.cores <- detectCores() - 1 

cl <- makeCluster(n.cores) 

registerDoParallel(cl) 

 

#names fits during loop

FITS <- foreach(id = names(tel), .packages = "ctmm") %dopar% {

  setNames(

    list({

      GUESS <- ctmm.guess(tel[[id]], interactive = FALSE)

      ctmm.select(tel[[id]], GUESS, trace = 2)

    }),

    id

  )

}

 

FITS <- unlist(FITS, recursive = FALSE)

 

 

stopCluster(cl)

rm(n.cores, cl)

 

saveRDS(FITS, "../data/FITS.rds")

 

#4 ref grid

# -----------------------------

#Build unified reference grid across all animals allie anderson

# -----------------------------

 

# Use ctmm-native extent

grid_extent <- ctmm::extent(tel)

 

# Compute ranges

x_range <- diff(grid_extent$x)

y_range <- diff(grid_extent$y)

 

# Buffer (used 5% — both are valid)

buffer_factor <- 0.05

 

buffered_extent <- list(

  x = c(grid_extent$x[1] - x_range * buffer_factor,

        grid_extent$x[2] + x_range * buffer_factor),

  y = c(grid_extent$y[1] - y_range * buffer_factor,

        grid_extent$y[2] + y_range * buffer_factor)

)

 

# Define grid resolution (meters, since UTM)

res <- 200 #did RAM calculation to come up with 200. default from allie =100

 

x_seq <- seq(buffered_extent$x[1], buffered_extent$x[2], by = res)

y_seq <- seq(buffered_extent$y[1], buffered_extent$y[2], by = res)

 

ref_grid <- list(x = x_seq, y = y_seq)

 

#5 akdes

AKDES_full <- lapply(names(tel), function(id) {

  akde(

    tel[[id]],

    FITS[[id]],

    weights = TRUE,

    debias = TRUE,

    grid = ref_grid

  )

})

names(AKDES_full) <- names(tel)

 

#6 overlap calculate

overlap_matrix = overlap(AKDES_full)

#output overlap matrix as df

overlap_matrix.df <- overlap_matrix$DOF

overlap_matrix.df <- cbind(

  Koala1 = rownames(overlap_matrix.df), as.data.frame(overlap_matrix.df)

)

 

#7. check uds were normalized with ref grid

 

#ref grid?

sapply(AKDES_full, function(x) paste(dim(x$PDF), collapse = "x"))

#projection same across inds?

sapply(AKDES_full, function(x) ctmm::projection(x))

#projection same for FITS, tel, UDs?

projection(FITS)

projection(tel)

projection(AKDES_full)

#yes -- all are "+proj=utm +zone=56 +south +ellps=GRS80 +units=m +no_defs"

Reply all
Reply to author
Forward
0 new messages