# Test edge_direction context('test edge_direction') library(spatsoc) DT <- fread('../testdata/DT.csv') id <- 'ID' datetime <- 'datetime' timethreshold <- '20 minutes' threshold <- 50 coords <- c('X', 'Y') timegroup <- 'timegroup' utm <- 32736 DT[, datetime := as.POSIXct(datetime, tz = 'UTC')] group_times(DT, datetime = datetime, threshold = timethreshold) edges <- edge_dist(DT, threshold = threshold, id = id, coords = coords, timegroup = timegroup, returnDist = TRUE, fillNA = FALSE) dyad_id(edges, id1 = 'ID1', id2 = 'ID2') clean_DT <- copy(DT) clean_edges <- copy(edges) test_that('edges, DT are required', { expect_error(edge_direction(edges, DT = NULL)) expect_error(edge_direction(edges = NULL, DT)) }) test_that('arguments required, otherwise error detected', { expect_error(edge_direction(edges, DT, id = id, coords = 'X'), 'coords must be length 2') expect_error(edge_direction(edges, DT, id = NULL), 'id must be provided') expect_error( edge_direction( edges, DT, id = id, coords = coords, timegroup = NULL ), 'timegroup must be' ) expect_error( edge_direction( edges, DT, id = id, coords = coords, timegroup = timegroup, crs = NULL ), 'crs must be' ) }) test_that('column names must exist in DT', { expect_error(edge_direction(edges, DT, id = 'potato', coords = coords, crs = utm), 'potato field') expect_error(edge_direction(edges, DT, id = id, coords = rep('potato', 2), crs = utm), 'potato field') copyDT <- copy(DT)[, timegroup := NULL] expect_error(edge_direction( edges, copyDT, id = id, coords = coords, crs = utm, timegroup = 'timegroup' ), 'timegroup field') copyEdges <- copy(edges)[, timegroup := NULL] expect_error( edge_direction( copyEdges, DT, id = id, coords = coords, crs = utm, timegroup = timegroup ), 'timegroup field' ) }) test_that('coords are correctly provided or error detected', { expect_error(edge_direction(edges, DT, id = id, coords = c('X', NULL)), 'coords must be length 2') expect_error(edge_direction(edges, DT, id = id, coords = c('X', 'ID')), 'coords must be of class numeric') }) test_that('direction_dyad column succesfully detected', { copyEdges <- copy(edges)[, direction_dyad := 1] expect_message( edge_direction( copyEdges, DT, id = id, coords = coords, crs = utm, timegroup = timegroup ), 'direction_dyad column will be overwritten' ) }) test_that('no rows are added to the result DT', { expect_equal(nrow(edges), nrow( edge_direction( edges, DT, id = id, coords = coords, crs = utm, timegroup = timegroup ) )) }) test_that('one columns added to the result DT', { copyEdges <- copy(edges) expect_equal(ncol(copyEdges) + 1, ncol( edge_direction( edges, DT, id = id, coords = coords, crs = utm, timegroup = timegroup ) )) }) test_that('column added to the result DT is unit', { expect_s3_class( edge_direction( edges, DT, id = id, coords = coords, crs = utm, timegroup = timegroup )$direction_dyad, 'units' ) }) test_that('returns a data.table', { expect_s3_class( edge_direction( edges, DT, id = id, coords = coords, crs = utm, timegroup = timegroup ), 'data.table' ) }) test_that('projection arg is deprecated', { expect_warning( edge_direction( edges, DT, id = id, coords = coords, timegroup = timegroup, projection = utm ), 'projection argument is deprecated' ) }) n <- 4 DT_B <- data.table( X = c(0, 5, 5, 0), Y = c(0, 0, 5, 5), timegroup = rep(1, n), ID = LETTERS[seq.int(n)] ) edges_B <- edge_dist(DT_B, id = id, coords = coords, timegroup = timegroup, threshold = NULL, returnDist = TRUE) dyad_id(edges_B, 'ID1', 'ID2') dyad_dirs <- edge_direction(edges_B, DT_B, id = id, coords = coords, crs = 4326) test_that('East North West South dyads', { tolerance <- 0.01 expect_equal( dyad_dirs[dyadID == 'A-B' & ID1 == 'A', direction_dyad], as_units(pi / 2, 'rad'), tolerance = tolerance ) expect_equal( dyad_dirs[dyadID == 'A-C' & ID1 == 'A', direction_dyad], as_units(pi / 4, 'rad'), tolerance = tolerance ) expect_equal( dyad_dirs[dyadID == 'A-D' & ID1 == 'A', direction_dyad], as_units(0, 'rad'), tolerance = tolerance ) expect_equal( dyad_dirs[dyadID == 'A-B' & ID1 == 'B', direction_dyad], -1 * as_units(pi / 2, 'rad'), tolerance = tolerance ) expect_equal( dyad_dirs[dyadID == 'B-C' & ID1 == 'C', direction_dyad], as_units(pi, 'rad'), tolerance = tolerance ) }) test_that('use_transform errors if crs not provided', { expect_error( edge_direction(edges, DT, id = id, coords = coords, crs = NA), 'ensure crs is provided' ) copyDT <- copy(DT) get_geometry(copyDT, coords = coords, crs = utm) st_crs(copyDT$geometry) <- NA expect_error( edge_direction(edges, copyDT, id = id), 'ensure crs is provided' ) }) # geometry interface test_that('if coords null, geometry required', { expect_error(edge_direction(edges, DT, id = id, coords = NULL), 'get_geometry?') }) test_that('crs provided with geometry gives message crs ignored', { get_geometry(DT, coords = coords, crs = utm) expect_message(edge_direction(edges, DT, id = id, crs = utm), 'ignored') }) test_that('geometry correctly provided else error', { expect_error(edge_direction(edges, DT, id = id, geometry = 'potato'), 'is not present') expect_error(edge_direction(edges, DT, id = id, geometry = 'X'), 'must be of class') }) test_that('geometry interface message before overwrite', { copyEdges <- copy(edges)[, direction_dyad := 42] expect_message(edge_direction(copyEdges, DT, id = id), 'overwritten') }) test_that('geometry interface returns expected', { copyEdges <- copy(edges) get_geometry(DT, coords = coords, crs = utm) expect_equal( ncol(copyEdges) + 1, ncol(edge_direction(copyEdges, DT, id = id)) ) expect_equal( nrow(copyEdges), nrow(edge_direction(copyEdges, DT, id = id)) ) expect_true('direction_dyad' %in% colnames(edge_direction(copyEdges, DT, id = id))) direction_step(DT, id = id) expect_true('direction' %in% colnames(edge_direction(copyEdges, DT, id = id))) outEdges <- edge_direction(copyEdges, DT, id = id) expect_type(outEdges$direction_dyad, 'double') expect_s3_class(outEdges$direction_dyad, 'units') expect_equal(max(outEdges$direction_dyad, na.rm = TRUE), units::as_units(pi, 'rad'), tolerance = 0.01) expect_equal(min(outEdges$direction_dyad, na.rm = TRUE), units::as_units(-pi, 'rad'), tolerance = 0.01) }) test_that('NAs in coordinates return NA', { copyDT <- copy(DT) full_edges <- edge_dist(DT, threshold = NULL, id = id, coords = coords, timegroup = timegroup, returnDist = TRUE, fillNA = TRUE) dyad_id(full_edges, id1 = 'ID1', id2 = 'ID2') copyDT[sample(.N, 100), X := NA] expect_lte( copyDT[is.na(X), .N], edge_direction( edges = full_edges, DT = copyDT, id = id, coords = coords, crs = utm, timegroup = timegroup )[is.na(direction_dyad), .N] ) copyDT <- copy(DT) copyDT[sample(.N, 100), Y := NA] expect_lte( copyDT[is.na(Y), .N], edge_direction( edges = full_edges, DT = copyDT, id = id, coords = coords, crs = utm, timegroup = timegroup )[is.na(direction_dyad), .N] ) }) test_that('geometry interface can manage edges and DT both with geometry', { copy_DT <- copy(clean_DT) copy_edges <- copy(clean_edges) get_geometry(copy_DT, coords = coords, crs = utm) fusion_id(edges = copy_edges, threshold = 50) cent <- centroid_fusion(edges = copy_edges, DT = copy_DT, id = id) expect_true('direction_dyad' %in% colnames(edge_direction(edges = cent, DT = copy_DT, id = id))) # And can manage if not present cent[, geometry := NULL] expect_true('direction_dyad' %in% colnames(edge_direction(edges = cent, DT = copy_DT, id = id))) })