# Test group_polys context('test group_polys') library(spatsoc) DT <- fread('../testdata/DT.csv') DT[, datetime := as.POSIXct(datetime)] DT[, family := sample(c(1, 2, 3, 4), .N, replace = TRUE)] DT[, jul := data.table::yday(datetime)] utm <- 32736 test_that('DT or spPts are required but not both', { expect_error(group_polys( DT = NULL, sfPolys = NULL, area = FALSE ), 'must provide either DT or sfPolys') expect_error(group_polys( DT = DT, sfPolys = 10, area = FALSE ), 'cannot provide both DT and sfPolys') }) test_that('id required', { expect_error(group_polys(DT, area = TRUE, id = NULL), 'id') }) test_that('area provided and logical, or error', { expect_error( group_polys( DT = DT, crs = utm, hrType = 'mcp', area = NULL, coords = c('X', 'Y'), id = 'ID' ), 'area must be provided', fixed = TRUE ) expect_error( group_polys( DT = DT, crs = utm, hrType = 'mcp', area = 'potato', coords = c('X', 'Y'), id = 'ID' ), 'area must be of class logical', fixed = TRUE ) expect_error( group_polys( DT = DT, crs = utm, hrType = 'mcp', area = NULL, coords = c('X', 'Y'), id = 'ID' ), 'area must be provided', fixed = TRUE ) }) test_that('id provided', { expect_error( group_polys( DT = DT, crs = utm, hrType = 'mcp', area = TRUE, coords = c('X', 'Y'), id = NULL ), 'id must be provided', fixed = TRUE ) }) test_that('crs provided or error', { expect_error( group_polys( DT = DT, crs = NULL, hrType = 'mcp', area = FALSE, coords = c('X', 'Y'), id = 'ID' ), 'crs must be provided' ) }) test_that('mising hrParams warns default used', { copyDT <- copy(DT) missingpromise <- evaluate_promise( group_polys( DT = copyDT, crs = utm, hrType = 'mcp', area = FALSE, coords = c('X', 'Y'), id = 'ID' ) ) expect_match( missingpromise$messages, 'hrParams is not provided, using defaults' ) }) test_that('missing hrType fails', { expect_error( group_polys( DT = DT, crs = utm, hrType = NULL, area = FALSE, coords = c('X', 'Y'), id = 'ID' ), 'hrType must be provided' ) }) test_that('column names must exist in DT', { expect_error( group_polys( DT = DT, crs = utm, hrType = 'mcp', area = FALSE, coords = c('X', 'Y'), id = 'potato' ), 'not present in input', fixed = FALSE ) expect_error( group_polys( DT = DT, crs = utm, hrType = 'mcp', area = FALSE, coords = c('potatoX', 'potatoY'), id = 'ID' ), 'not present in input', fixed = FALSE ) expect_error( group_polys( DT = DT, crs = utm, hrType = 'mcp', area = FALSE, coords = c('X', 'Y'), id = 'ID', splitBy = 'potato' ), 'not present in input', fixed = FALSE ) }) test_that('splitBy and sfPolys are not both provided', { expect_error( group_polys( splitBy = 'yr', sfPolys = 10, area = TRUE ), 'cannot provide sfPolys if providing splitBy' ) }) test_that('ID field does not have spaces', { copyDT <- copy(DT)[ID == unique(ID)[1], ID := paste(ID, ID)] idpromise <- evaluate_promise( expect_error(group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID' )) ) expect_match( as.character(idpromise$result), 'please ensure IDs do not contain spaces' ) copyDT[, population := 1] expect_error( group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID', splitBy = 'population' ), 'please ensure IDs do not contain spaces' ) }) test_that('column and row lengths returned make sense', { copyDT <- copy(DT) group_polys_mcp <- group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID' ) expect_lte(nrow(group_polys_mcp), nrow(expand.grid(DT[, unique(ID)], DT[, unique(ID)]))) copyDT <- copy(DT)[, yr := year(datetime)] group_polys_mcp_split <- group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = FALSE, coords = c('X', 'Y'), id = 'ID', splitBy = 'yr' ) expect_equal(nrow(group_polys_mcp_split), nrow(copyDT)) group_sf_polys <- group_polys( id = 'ID', area = FALSE, sfPolys = build_polys( DT = DT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), coords = c('X', 'Y'), id = 'ID' ) ) group_sf_polys_area <- group_polys( id = 'ID', area = TRUE, sfPolys = build_polys( DT = DT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), coords = c('X', 'Y'), id = 'ID' ) ) expect_length(unique(DT$ID), nrow(group_sf_polys)) expect_equal(nrow(group_sf_polys_area), length(unique(DT$ID)) ^ 2) }) test_that('withinGroup is not returned to the user', { copyDT <- copy(DT)[, datetime := as.POSIXct(datetime)] # to avoid block length warning suppressWarnings( group_times(copyDT, datetime = 'datetime', threshold = '14 days') ) copyDT[, N := .N, by = .(ID, block)] within_group <- group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = FALSE, coords = c('X', 'Y'), id = 'ID' ) expect_false('withinGroup' %in% colnames(within_group)) }) test_that('group column succesfully detected', { copyDT <- copy(DT)[, group := 1][, mnth := month(datetime)] copyDT <- copyDT[, nBy := .N, by = .(mnth, ID)][nBy > 30] groupdelpromise <- evaluate_promise( group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = FALSE, coords = c('X', 'Y'), id = 'ID', splitBy = 'mnth' ) ) expect_match(groupdelpromise$messages, 'group column will be overwritten') copyDT <- copy(DT)[, group := 1][, mnth := month(datetime)] copyDT <- copyDT[, nBy := .N, by = .(mnth, ID)][nBy > 30] overwritepromise <- evaluate_promise( group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = FALSE, coords = c('X', 'Y'), id = 'ID' ) ) expect_match( overwritepromise$messages, 'group column will be overwritten' ) }) test_that('area provided with splitBy does not return errors', { copyDT <- copy(DT)[, datetime := as.POSIXct(datetime)] copyDT[, yr := year(datetime)] within_split <- group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID', splitBy = 'yr' ) expect_false('withinGroup' %in% colnames(within_split)) area <- group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID', splitBy = 'yr' ) expect_true('area' %in% colnames(area)) prop <- group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID', splitBy = 'yr' ) expect_true('proportion' %in% colnames(prop)) }) test_that('less than 5 locs returns NAs and warning', { copyDT <- copy(DT)[, datetime := as.POSIXct(datetime)] copyDT[, yr := year(datetime)] copyDT[1, yr := 2020] expect_warning( group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID', splitBy = 'yr' ), 'build_polys failed for some rows', fixed = FALSE ) expect_warning( group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = FALSE, coords = c('X', 'Y'), id = 'ID', splitBy = 'yr' ), 'build_polys failed for some rows', fixed = FALSE ) expect_true( suppressWarnings(group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = FALSE, coords = c('X', 'Y'), id = 'ID', splitBy = 'yr' )[is.na(group), .N != 0] )) expect_true( suppressWarnings(group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID', splitBy = 'yr' )[is.na(area), .N != 0] )) }) test_that('splitBy argument doesnt use splitBy column', { copyDT <- copy(DT) copyDT[, splitBy := family] utm <- 32736 expect_true( suppressWarnings(group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = FALSE, coords = c('X', 'Y'), id = 'ID', splitBy = 'jul' ))[, uniqueN(jul), group][, all(V1 == 1)] ) expect_false('splitBy' %in% suppressWarnings(group_polys( DT = copyDT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID', splitBy = 'jul' ))) }) test_that('proportion within 0-100, area > 0', { out_mcp <- suppressWarnings(group_polys( DT = DT, crs = utm, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID' )) expect_gte(min(out_mcp$proportion), units::as_units(0, 'percent')) expect_lte(max(out_mcp$proportion), units::as_units(100.01, 'percent')) expect_gte(min(out_mcp$area), units::as_units(0, 'm^2')) out_kernel <- suppressWarnings(group_polys( DT = DT, crs = utm, hrType = 'kernel', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID' )) expect_gte(min(out_kernel$proportion), units::as_units(0, 'percent')) expect_lte(max(out_kernel$proportion), units::as_units(100.01, 'percent')) expect_gte(min(out_kernel$area), units::as_units(0, 'm^2')) }) test_that('sfPolys has area column', { sfPolys <- build_polys(DT, crs = utm, hrType = 'kernel', hrParams = list(grid = 60, percent = 95), id = 'ID', coords = c('X', 'Y')) sfPolys$area <- NULL expect_error( group_polys(sfPolys = sfPolys, area = TRUE, id = 'id'), 'please ensure column "area"', fixed = TRUE ) }) test_that('projection arg is deprecated', { expect_warning( group_polys( DT = DT, hrType = 'mcp', hrParams = list(percent = 95), area = TRUE, coords = c('X', 'Y'), id = 'ID', projection = utm ), 'projection argument is deprecated' ) })