From aa7819c9a4fe5005f731cc2dc8b7c9deed685220 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Wed, 1 Nov 2023 13:55:23 +0000 Subject: [PATCH 01/19] Modernise tests for classes --- tests/testthat/test_classes.R | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test_classes.R b/tests/testthat/test_classes.R index e019f46..03fcc06 100644 --- a/tests/testthat/test_classes.R +++ b/tests/testthat/test_classes.R @@ -1,10 +1,8 @@ library("geoGraph") -context("Test classes") test_that("Empty constructors work", { - skip_on_cran() x <- new("gGraph") + expect_true(inherits(x,"gGraph")) y <- new("gData") - expect_is(x, "gGraph") - expect_is(y, "gData") + expect_true(inherits(y,"gData")) }) From e099cbde52551555348515f2417deceea30f4f65 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Wed, 1 Nov 2023 14:07:28 +0000 Subject: [PATCH 02/19] add test for findLand --- tests/testthat/test_classes.R | 1 - tests/testthat/test_findLand.R | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/testthat/test_findLand.R diff --git a/tests/testthat/test_classes.R b/tests/testthat/test_classes.R index 03fcc06..3797600 100644 --- a/tests/testthat/test_classes.R +++ b/tests/testthat/test_classes.R @@ -1,4 +1,3 @@ -library("geoGraph") test_that("Empty constructors work", { x <- new("gGraph") diff --git a/tests/testthat/test_findLand.R b/tests/testthat/test_findLand.R new file mode 100644 index 0000000..a7f5951 --- /dev/null +++ b/tests/testthat/test_findLand.R @@ -0,0 +1,8 @@ +test_that("find land correctly",{ + # create a gGraph with one sea node and one land node + myCoords <- data.frame(long = c(-24, 37), lat = c(31,55)) + obj <- new("gGraph", coords = myCoords) + obj <- findLand(obj) + # check that we classified the nodes correctly + expect_true(all(obj@nodes.attr$habitat==c("sea","land"))) +}) \ No newline at end of file From 18a6da0af55a231b15b5a44529be4c9ed60dd4f8 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Wed, 1 Nov 2023 14:12:06 +0000 Subject: [PATCH 03/19] check error messag for incorrect class --- tests/testthat/test_findLand.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/testthat/test_findLand.R b/tests/testthat/test_findLand.R index a7f5951..4caebda 100644 --- a/tests/testthat/test_findLand.R +++ b/tests/testthat/test_findLand.R @@ -5,4 +5,8 @@ test_that("find land correctly",{ obj <- findLand(obj) # check that we classified the nodes correctly expect_true(all(obj@nodes.attr$habitat==c("sea","land"))) + + # error if we pass an incorrect class + expect_error(findLand("blah"), + "unable to find an inherited method") }) \ No newline at end of file From 774eaae0ade3e78739674ee54cf69d675a74834e Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Wed, 1 Nov 2023 21:01:39 +0000 Subject: [PATCH 04/19] quick overlap algorithm --- R/extractFromLayer.R | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/R/extractFromLayer.R b/R/extractFromLayer.R index 6d3a3e7..c4a6f7b 100644 --- a/R/extractFromLayer.R +++ b/R/extractFromLayer.R @@ -95,35 +95,46 @@ setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all ## Load default shapefile ## if (is.character(layer) && layer[1] == "world") { - layer <- worldshape + # layer <- worldshape + layer <- sf::st_read(system.file("files/shapefiles/world-countries.shp", package = "geoGraph")) } ## TODO if the layer is null, we should throw an error!!! if (!is.null(layer)) { if (!inherits(layer, "SpatialPolygonsDataFrame")) { - stop("Layer must be a SpatialPolygonsDataFrame object \n(see st_read and as_Spatial in sf to import such data from a GIS shapefile).") +# stop("Layer must be a SpatialPolygonsDataFrame object \n(see st_read and as_Spatial in sf to import such data from a GIS shapefile).") } } ## search attr in data ## if (attr[1] == "all") { - selAttr <- 1:ncol(layer@data) + selAttr <- 1:ncol(layer) } else { - selAttr <- match(attr, colnames(layer@data)) # selected attributes + selAttr <- match(attr, colnames(layer)) # selected attributes if (any(is.na(selAttr))) { # attribute not found in layer@data cat("\nSome requested attribute (attr) not found in the layer.\n") cat("\nAvailable data are:\n") - print(utils::head(layer@data)) + print(utils::head(layer)) return(NULL) # return NULL if attr not found, not generate an error } } + # create an sf point object from the coordinates + locations_st <- x %>% as.data.frame %>%sf::st_as_sf(coords=c(1,2)) + points_within <- sf::st_within(locations_st, layer) + points_within <- sf::st_join(locations_st, layer, join = sf::st_within) + points_within <- sf::st_intersects(layer, locations_st) + points_within <- data.frame(x = unlist(points_within), + polygon = rep(seq_along(lengths(points_within)), lengths(points_within))) + + + ## variables and initialization ## long <- unlist(x[, 1]) # unlist needed when nrow==1 lat <- unlist(x[, 2]) n.poly.list <- length(layer@polygons) # number of lists of Polygons obj. res <- NULL - dat <- layer@data + dat <- layer layerId <- rep(NA, length(long)) # stores the id of matching polygon for each location From 8bbe459f4bf85cf0d1d7c91e6237eb8df31ec234 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Wed, 1 Nov 2023 21:25:37 +0000 Subject: [PATCH 05/19] Use sf for extractFromLayer --- R/extractFromLayer.R | 55 ++++++++------------------------------------ 1 file changed, 9 insertions(+), 46 deletions(-) diff --git a/R/extractFromLayer.R b/R/extractFromLayer.R index c4a6f7b..26e1111 100644 --- a/R/extractFromLayer.R +++ b/R/extractFromLayer.R @@ -49,15 +49,9 @@ #' #' plot(worldgraph.10k, reset = TRUE) #' -#' -#' ## see what info is available -#' names(worldshape@data) -#' unique(worldshape@data$CONTINENT) -#' -#' #' ## retrieve continent info for all nodes #' ## (might take a few seconds) -#' x <- extractFromLayer(worldgraph.10k, layer = worldshape, attr = "CONTINENT") +#' x <- extractFromLayer(worldgraph.10k, layer = "world", attr = "CONTINENT") #' x #' table(getNodesAttr(x, attr.name = "CONTINENT")) #' @@ -121,47 +115,16 @@ setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all # create an sf point object from the coordinates locations_st <- x %>% as.data.frame %>%sf::st_as_sf(coords=c(1,2)) - points_within <- sf::st_within(locations_st, layer) - points_within <- sf::st_join(locations_st, layer, join = sf::st_within) + # now find points in polygons points_within <- sf::st_intersects(layer, locations_st) points_within <- data.frame(x = unlist(points_within), polygon = rep(seq_along(lengths(points_within)), lengths(points_within))) - - - - ## variables and initialization ## - long <- unlist(x[, 1]) # unlist needed when nrow==1 - lat <- unlist(x[, 2]) - n.poly.list <- length(layer@polygons) # number of lists of Polygons obj. - res <- NULL - dat <- layer - layerId <- rep(NA, length(long)) # stores the id of matching polygon for each location - - - ## main computations ## - - ## browsing elements of @polygons - ## each is a list with a @Polygons slot - for (i in 1:n.poly.list) { - this.poly.list <- layer@polygons[[i]] - n.polys <- length(this.poly.list@Polygons) - points.in.this.poly <- rep(0, length(long)) - - ## browsing elements of @Polygons - for (j in 1:n.polys) { ## - this.poly <- this.poly.list@Polygons[[j]] - points.in.this.poly <- points.in.this.poly + - sp::point.in.polygon(long, lat, this.poly@coords[, 1], this.poly@coords[, 2]) - - points.in.this.poly <- as.logical(points.in.this.poly) - - if (any(points.in.this.poly)) { - layerId[points.in.this.poly] <- this.poly.list@ID - } - } # end for j - } # end for i - - res <- dat[layerId, selAttr, drop = FALSE] + points_assignment <- data.frame(x=seq(1, nrow(x)), polygon = NA) + # add missing points for which we have no information + points_assignment[points_within$x,"polygon"]<-points_within$polygon + + dat <- layer %>% sf::st_drop_geometry() + res <- dat[points_assignment$polygon, selAttr, drop = FALSE] row.names(res) <- rownames(x) return(res) @@ -248,4 +211,4 @@ setMethod("extractFromLayer", "gData", function(x, layer = "world", attr = "all" } return(x) -}) # end findLand +}) From 08af23d77a78a652595328111dfc0ecfea25dd4f Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Wed, 1 Nov 2023 21:43:47 +0000 Subject: [PATCH 06/19] Fix use of rnaturalearth --- R/extractFromLayer.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/extractFromLayer.R b/R/extractFromLayer.R index 26e1111..3a95eda 100644 --- a/R/extractFromLayer.R +++ b/R/extractFromLayer.R @@ -84,6 +84,8 @@ setGeneric("extractFromLayer", function(x, ...) { #' @rdname extractFromLayer #' @export setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all", ...) { + sf::sf_use_s2(FALSE) + ## This functions automatically assigns to land all points overlapping the country polygons # if(!require(maptools)) stop("maptools package is required.") @@ -114,7 +116,9 @@ setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all } # create an sf point object from the coordinates - locations_st <- x %>% as.data.frame %>%sf::st_as_sf(coords=c(1,2)) + locations_st <- x %>% as.data.frame %>% + sf::st_as_sf(coords=c(1,2)) %>% + sf::st_set_crs(sf::st_crs(layer)) # now find points in polygons points_within <- sf::st_intersects(layer, locations_st) points_within <- data.frame(x = unlist(points_within), From 8f5c729ad288ca4bc6d46d449f59d7fa98dc1835 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Wed, 1 Nov 2023 21:48:34 +0000 Subject: [PATCH 07/19] how to use rnaturalearth --- R/extractFromLayer.R | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/R/extractFromLayer.R b/R/extractFromLayer.R index 3a95eda..06d45ab 100644 --- a/R/extractFromLayer.R +++ b/R/extractFromLayer.R @@ -91,14 +91,15 @@ setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all ## Load default shapefile ## if (is.character(layer) && layer[1] == "world") { - # layer <- worldshape + # use rnaturalearth instead of the inbuilt dataset + # layer <- rnaturalearth::ne_countries(scale="medium", returnclass = "sf") layer <- sf::st_read(system.file("files/shapefiles/world-countries.shp", package = "geoGraph")) } ## TODO if the layer is null, we should throw an error!!! if (!is.null(layer)) { - if (!inherits(layer, "SpatialPolygonsDataFrame")) { -# stop("Layer must be a SpatialPolygonsDataFrame object \n(see st_read and as_Spatial in sf to import such data from a GIS shapefile).") + if (!inherits(layer, "sf")) { + stop("Layer must be a sf object \n(see st_read in sf to import such data from a GIS shapefile).") } } From 6323e5fd47465c50ad9f1b0c8205d4c21b0a81ad Mon Sep 17 00:00:00 2001 From: Evie Carter Date: Wed, 8 Nov 2023 06:56:59 +0000 Subject: [PATCH 08/19] Starting notes for test of NA values --- tests/testthat/test_findLand.R | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test_findLand.R b/tests/testthat/test_findLand.R index 4caebda..397253b 100644 --- a/tests/testthat/test_findLand.R +++ b/tests/testthat/test_findLand.R @@ -9,4 +9,30 @@ test_that("find land correctly",{ # error if we pass an incorrect class expect_error(findLand("blah"), "unable to find an inherited method") -}) \ No newline at end of file + +}) + + +#Test whether findLand generates an error with invalid object +test_that("co-ordinate format",{ + #Create co-ordinates + obj <- matrix(c(-24, 31, 37, 55), nrow=2,ncol=2, byrow=TRUE) + obj <- findLand(obj) + + #check for factor output + expect_is(obj,"factor") + #check for correct output + expect_equal(obj,factor(c('sea','land'))) + + #obj1 <- matrix(c(-24, NA, 37, 55), nrow=2,ncol=2, byrow=TRUE) + #NA entries in matrix do not produce error + #expect_error(findLand(obj1)) + + + + #obj2 <- data.frame(long = c(-24, 37), lat = c(31,55)) + #expect_error(obj2 <- findLand()) +}) + + + From d6f704a06c02dfa603686585de67df6ad7a2139e Mon Sep 17 00:00:00 2001 From: Evie Carter Date: Tue, 14 Nov 2023 12:00:09 +0000 Subject: [PATCH 09/19] Adding NA test and an if NA statement to findLand function --- R/findLand.R | 4 ++++ tests/testthat/test_findLand.R | 27 ++++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/R/findLand.R b/R/findLand.R index a187d40..d5ade2c 100644 --- a/R/findLand.R +++ b/R/findLand.R @@ -91,6 +91,10 @@ setMethod("findLand", "matrix", function(x, shape = "world", ...) { } } + if (any(is.na(x))) { + stop("Matrix contains NA values.") + } + long <- x[, 1] lat <- x[, 2] n.country <- length(shape@polygons) diff --git a/tests/testthat/test_findLand.R b/tests/testthat/test_findLand.R index 397253b..73af25a 100644 --- a/tests/testthat/test_findLand.R +++ b/tests/testthat/test_findLand.R @@ -9,13 +9,24 @@ test_that("find land correctly",{ # error if we pass an incorrect class expect_error(findLand("blah"), "unable to find an inherited method") + + #Create gGraph with NA's + NACoords <- data.frame(long = c(-24, NA), lat = c(31,55)) + NA_gGraph <- new("gGraph", coords = NACoords) + + #NA entries are recognised and produce error in plot + expect_error(plot(NA_gGraph)) + + #NA produces error in findLand + expect_error(findLand(NA_gGraph)) + }) -#Test whether findLand generates an error with invalid object +#Test whether findLand generates an error with invalid matrix object test_that("co-ordinate format",{ - #Create co-ordinates + #Create co-ordinates matrix obj <- matrix(c(-24, 31, 37, 55), nrow=2,ncol=2, byrow=TRUE) obj <- findLand(obj) @@ -24,14 +35,16 @@ test_that("co-ordinate format",{ #check for correct output expect_equal(obj,factor(c('sea','land'))) - #obj1 <- matrix(c(-24, NA, 37, 55), nrow=2,ncol=2, byrow=TRUE) - #NA entries in matrix do not produce error - #expect_error(findLand(obj1)) + #Create co-ordinates matrix with NA + NA_matrix <- matrix(c(-24, NA, 37, 55), nrow=2,ncol=2, byrow=TRUE) + #NA entries are recognised and produce error in plot + expect_true(is.na(NA_matrix[1,2])) + expect_error(plotEdges(NA_matrix)) + #NA produces error in findLand + expect_error(findLand(NA_matrix)) - #obj2 <- data.frame(long = c(-24, 37), lat = c(31,55)) - #expect_error(obj2 <- findLand()) }) From 8d5d5f8af5d2fcd6711a701ae6e74d9b47a677c9 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Tue, 14 Nov 2023 13:41:00 +0000 Subject: [PATCH 10/19] Update version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9ad1686..679bfed 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: geoGraph Type: Package Title: Walking through the geographic space using graphs -Version: 1.1.1.9001 +Version: 1.1.1.9002 Author: Thibaut Jombart, Andrea Manica Maintainer: Andrea Manica From 8009b3fd91d7dbcd70f732c7f325289ee62eaebb Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Tue, 28 Nov 2023 14:05:23 +0000 Subject: [PATCH 11/19] check for NAs in gGraph constructor --- R/classes.R | 10 +++++++++- tests/testthat/test_classes.R | 8 ++++++++ tests/testthat/test_findLand.R | 13 +++++-------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/R/classes.R b/R/classes.R index 48a9da7..77ef972 100644 --- a/R/classes.R +++ b/R/classes.R @@ -289,7 +289,15 @@ setMethod("initialize", "gGraph", function(.Object, ...) { input$coords <- as.matrix(input$coords) } - if (nrow(input$coords) > 0 && !is.numeric(input$coords)) stop("Argument coords has to be numeric.") + if (nrow(input$coords) > 0 && !is.numeric(input$coords)) { + stop("Argument coords has to be numeric.") + } + + ## NAs in coords + if (any(is.na(input$coords))) { + stop("Argument coords includes NAs") + } + ## names of the matrix colnames(input$coords) <- c("lon", "lat") diff --git a/tests/testthat/test_classes.R b/tests/testthat/test_classes.R index 3797600..8263dc2 100644 --- a/tests/testthat/test_classes.R +++ b/tests/testthat/test_classes.R @@ -5,3 +5,11 @@ test_that("Empty constructors work", { y <- new("gData") expect_true(inherits(y,"gData")) }) + +test_that("Contructors fails with invalid coordinates",{ + NACoords <- data.frame(long = c(-24, NA), lat = c(31,55)) + #Create gGraph with NA's + expect_error(new("gGraph", coords = NACoords), + "Argument coords includes NAs") + +}) \ No newline at end of file diff --git a/tests/testthat/test_findLand.R b/tests/testthat/test_findLand.R index 73af25a..a8c85d2 100644 --- a/tests/testthat/test_findLand.R +++ b/tests/testthat/test_findLand.R @@ -10,16 +10,13 @@ test_that("find land correctly",{ expect_error(findLand("blah"), "unable to find an inherited method") - #Create gGraph with NA's + # tests error for NAs as coordinates (this only applies to matrices and data.frames) + # gGraph objects should fail when creted with NA coordinates NACoords <- data.frame(long = c(-24, NA), lat = c(31,55)) - NA_gGraph <- new("gGraph", coords = NACoords) - - #NA entries are recognised and produce error in plot - expect_error(plot(NA_gGraph)) - - #NA produces error in findLand - expect_error(findLand(NA_gGraph)) + expect_error(findLand(NACoords), + "Matrix contains NA") + }) From 244938b91c306b9a5e6c3a40dcd6fb51ad2b620a Mon Sep 17 00:00:00 2001 From: m-colucci Date: Mon, 4 Dec 2023 21:06:48 +0100 Subject: [PATCH 12/19] check numeric coordinates and ncol --- R/classes.R | 4 ++++ tests/testthat/test_classes.R | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/R/classes.R b/R/classes.R index 77ef972..fff4b82 100644 --- a/R/classes.R +++ b/R/classes.R @@ -281,6 +281,10 @@ setMethod("initialize", "gGraph", function(.Object, ...) { ## handle @coords ## if (!is.null(input$coords)) { + if (is.list(input$coords) && length(input$coords) > 2) { + stop("Argument coords must include only two columns (longitude and latitude).") + } + if (is.list(input$coords) && length(input$coords) == 2) { input$coords <- as.data.frame(input$coords) } diff --git a/tests/testthat/test_classes.R b/tests/testthat/test_classes.R index 8263dc2..d6c0513 100644 --- a/tests/testthat/test_classes.R +++ b/tests/testthat/test_classes.R @@ -12,4 +12,20 @@ test_that("Contructors fails with invalid coordinates",{ expect_error(new("gGraph", coords = NACoords), "Argument coords includes NAs") -}) \ No newline at end of file +}) + +test_that("Contructors fails with invalid matrix dimensions",{ + extra_coords <- data.frame(long = c(-24, 37), lat = c(31,55), x = c(31,31)) + #Create gGraph with three columns + expect_error(new("gGraph", coords = extra_coords), + "Argument coords must include") + +}) + +test_that("Contructors fails with invalid non-numeric matrix",{ + non_num_coords <- data.frame(long = c("lon1", 37), lat = c(31,55)) + #Create gGraph with non numeric elements + expect_error(new("gGraph", coords = non_num_coords), + "Argument coords has to be numeric") + +}) From 293371a0a72edecb8543856a50835f649f91eb99 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Tue, 5 Dec 2023 13:08:25 +0000 Subject: [PATCH 13/19] docs fixes --- DESCRIPTION | 14 +++++++++----- NAMESPACE | 2 ++ R/extractFromLayer.R | 9 +++++++-- R/utils-pipe.R | 14 ++++++++++++++ man/buffer.Rd | 34 +++++++++++++++++----------------- man/closestNode.Rd | 17 ++++++++--------- man/dijkstra-methods.Rd | 15 +++++++-------- man/dropDeadEdges.Rd | 3 +-- man/extractFromLayer.Rd | 18 +++++------------- man/findLand.Rd | 7 +++---- man/gData-class.Rd | 11 +++++------ man/gGraph-class.Rd | 15 +++++++-------- man/geo.add.edges.Rd | 9 ++++----- man/geo.change.attr.Rd | 15 +++++++-------- man/geoGraph-package.Rd | 13 ++++++------- man/getColors.Rd | 3 +-- man/getCosts.Rd | 4 ++-- man/getEdges.Rd | 4 ++-- man/getNodesAttr.Rd | 1 - man/hgdp.Rd | 18 +++++++++--------- man/isInArea.Rd | 10 +++++----- man/makeGrid.Rd | 10 ++++++---- man/pipe.Rd | 20 ++++++++++++++++++++ man/plot-gData.Rd | 19 +++++++++---------- man/plot-gGraph.Rd | 19 +++++++++---------- man/setCosts.Rd | 9 ++++----- man/setDistCosts.Rd | 22 +++++++++++----------- man/worldgraph.Rd | 15 +++++++-------- man/zoom.Rd | 11 +++++------ 29 files changed, 192 insertions(+), 169 deletions(-) create mode 100644 R/utils-pipe.R create mode 100644 man/pipe.Rd diff --git a/DESCRIPTION b/DESCRIPTION index c524be3..e85deb0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -17,14 +17,17 @@ Depends: methods, graph Imports: - fields, - RBGL, - sp + fields, + RBGL, + rnaturalearth, + rnaturalearthdata, + sp, + sf, + magrittr Suggests: testthat, knitr, - rmarkdown, - sf + rmarkdown RoxygenNote: 7.2.3 Collate: 'classes.R' @@ -48,5 +51,6 @@ Collate: 'rebuild.R' 'setCosts.R' 'setDistCosts.R' + 'utils-pipe.R' 'zoom.R' 'zzz.R' diff --git a/NAMESPACE b/NAMESPACE index 243f0ad..03aae94 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand S3method(plot,gPath) +export("%>%") export() export(.gData.valid) export(.gGraph.valid) @@ -76,3 +77,4 @@ import(sp) importFrom(graphics,identify) importFrom(graphics,locator) importFrom(graphics,segments) +importFrom(magrittr,"%>%") diff --git a/R/extractFromLayer.R b/R/extractFromLayer.R index 06d45ab..5f0b6a3 100644 --- a/R/extractFromLayer.R +++ b/R/extractFromLayer.R @@ -84,7 +84,7 @@ setGeneric("extractFromLayer", function(x, ...) { #' @rdname extractFromLayer #' @export setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all", ...) { - sf::sf_use_s2(FALSE) + ## This functions automatically assigns to land all points overlapping the country polygons # if(!require(maptools)) stop("maptools package is required.") @@ -93,13 +93,18 @@ setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all if (is.character(layer) && layer[1] == "world") { # use rnaturalearth instead of the inbuilt dataset # layer <- rnaturalearth::ne_countries(scale="medium", returnclass = "sf") + # sf::sf_use_s2(FALSE) layer <- sf::st_read(system.file("files/shapefiles/world-countries.shp", package = "geoGraph")) } ## TODO if the layer is null, we should throw an error!!! if (!is.null(layer)) { if (!inherits(layer, "sf")) { - stop("Layer must be a sf object \n(see st_read in sf to import such data from a GIS shapefile).") + if (inherits(layer, "SpatialPolygonsDataFrame")){ + layer <- sf::st_as_sf(layer) + } else { + stop("Layer must be a sf object \n(see st_read in sf to import such data from a GIS shapefile).") + } } } diff --git a/R/utils-pipe.R b/R/utils-pipe.R new file mode 100644 index 0000000..fd0b1d1 --- /dev/null +++ b/R/utils-pipe.R @@ -0,0 +1,14 @@ +#' Pipe operator +#' +#' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. +#' +#' @name %>% +#' @rdname pipe +#' @keywords internal +#' @export +#' @importFrom magrittr %>% +#' @usage lhs \%>\% rhs +#' @param lhs A value or the magrittr placeholder. +#' @param rhs A function call using the magrittr semantics. +#' @return The result of calling `rhs(lhs)`. +NULL diff --git a/man/buffer.Rd b/man/buffer.Rd index 82699b6..c7220ff 100644 --- a/man/buffer.Rd +++ b/man/buffer.Rd @@ -50,33 +50,33 @@ location they surround. #### gGraph example #### ## zoom in to an area -plot(worldgraph.10k, reset=TRUE) -geo.zoomin(list(x=c(-6,38), y=c(35,73))) +plot(worldgraph.10k, reset = TRUE) +geo.zoomin(list(x = c(-6, 38), y = c(35, 73))) ## identify one node -oneNodeXY <- c(getCoords(worldgraph.10k)[9299,1],getCoords(worldgraph.10k)[9299,2]) -points(oneNodeXY[1], oneNodeXY[2], col="red") +oneNodeXY <- c(getCoords(worldgraph.10k)[9299, 1], getCoords(worldgraph.10k)[9299, 2]) +points(oneNodeXY[1], oneNodeXY[2], col = "red") ## find some buffers buffer(worldgraph.10k, "9299", 100) # nothing around 100km buffer(worldgraph.10k, "9299", 500) -buf500km <- buffer(worldgraph.10k, "9299", 500, res="gGraph") -plot(buf500km, col.rules=buf500km@meta$buf.colors) -buf1000km <- buffer(worldgraph.10k, "9299", 1000, res="gGraph") -plot(buf1000km, col.rules=buf1000km@meta$buf.colors) +buf500km <- buffer(worldgraph.10k, "9299", 500, res = "gGraph") +plot(buf500km, col.rules = buf500km@meta$buf.colors) +buf1000km <- buffer(worldgraph.10k, "9299", 1000, res = "gGraph") +plot(buf1000km, col.rules = buf1000km@meta$buf.colors) #### gData example #### x <- hgdp[27:30] # retain a subset of hgdp -plot(x, reset=TRUE, col.g="lightgrey", pch.node=20) -buf.200 <- buffer(x, 200, res="gData") -buf.400 <- buffer(x, 400, res="gData") -buf.600 <- buffer(x, 600, res="gData") -buf.1000 <- buffer(x, 1000, res="gData") -points(buf.1000, col.node="black") -points(buf.600, col.node="yellow") -points(buf.400, col.node="gold") -points(buf.200, col.node="orange") +plot(x, reset = TRUE, col.g = "lightgrey", pch.node = 20) +buf.200 <- buffer(x, 200, res = "gData") +buf.400 <- buffer(x, 400, res = "gData") +buf.600 <- buffer(x, 600, res = "gData") +buf.1000 <- buffer(x, 1000, res = "gData") +points(buf.1000, col.node = "black") +points(buf.600, col.node = "yellow") +points(buf.400, col.node = "gold") +points(buf.200, col.node = "orange") title("Different buffers for a gData \n(100km, 200km, 500km)") } diff --git a/man/closestNode.Rd b/man/closestNode.Rd index f7dffca..fe340a7 100644 --- a/man/closestNode.Rd +++ b/man/closestNode.Rd @@ -68,33 +68,32 @@ that it is not possible to specify node attributes (\code{attr.names} and }} \examples{ - \dontrun{ ## interactive example ## -plot(worldgraph.10k, reset=TRUE) +plot(worldgraph.10k, reset = TRUE) ## zooming in -geo.zoomin(list(x=c(-6,38), y=c(35,73))) +geo.zoomin(list(x = c(-6, 38), y = c(35, 73))) title("Europe") ## click some locations -myNodes <- closestNode(worldgraph.10k,locator(), attr.name="habitat", attr.value="land") +myNodes <- closestNode(worldgraph.10k, locator(), attr.name = "habitat", attr.value = "land") myNodes ## here are the closestNodes -points(getCoords(worldgraph.10k)[myNodes,], col="red") +points(getCoords(worldgraph.10k)[myNodes, ], col = "red") } ## example with a gData object ## -myLoc <- list(x=c(3, -8, 11, 28), y=c(50, 57, 71, 67)) # some locations -obj <- new("gData", coords=myLoc) # new gData object +myLoc <- list(x = c(3, -8, 11, 28), y = c(50, 57, 71, 67)) # some locations +obj <- new("gData", coords = myLoc) # new gData object obj obj@gGraph.name <- "worldgraph.10k" # this could be done when creating obj -obj <- closestNode(obj, attr.name="habitat", attr.value="land") +obj <- closestNode(obj, attr.name = "habitat", attr.value = "land") ## plot the result (original location -> assigned node) -plot(obj, method="both", reset=TRUE) +plot(obj, method = "both", reset = TRUE) title("'x'=location, 'o'=assigned node") diff --git a/man/dijkstra-methods.Rd b/man/dijkstra-methods.Rd index 3ebc6eb..dd0bfe6 100644 --- a/man/dijkstra-methods.Rd +++ b/man/dijkstra-methods.Rd @@ -89,28 +89,27 @@ In 'dijkstraBetween', paths are seeked all possible pairs of nodes between 'from' and 'to'. } \examples{ - \dontrun{ ## plotting world <- worldgraph.40k -par(mar=rep(.1,4)) -plot(world, reset=TRUE) +par(mar = rep(.1, 4)) +plot(world, reset = TRUE) ## check connectivity isConnected(hgdp) # must be ok ## Lowest cost path from an hypothetical origin -ori.coord <- list(33,10) # one given location long/lat -points(data.frame(ori.coord), pch="x", col="black", cex=3) # an 'x' shows the putative origin +ori.coord <- list(33, 10) # one given location long/lat +points(data.frame(ori.coord), pch = "x", col = "black", cex = 3) # an 'x' shows the putative origin ori <- closestNode(world, ori.coord) # assign it the closest node myPath <- dijkstraFrom(hgdp, ori) # compute shortest path ## plotting -plot(world,pch="") # plot the world -points(hgdp, lwd=3) # plot populations -points(data.frame(ori.coord), pch="x", col="black", cex=3) # add origin +plot(world, pch = "") # plot the world +points(hgdp, lwd = 3) # plot populations +points(data.frame(ori.coord), pch = "x", col = "black", cex = 3) # add origin plot(myPath) # plot the path } diff --git a/man/dropDeadEdges.Rd b/man/dropDeadEdges.Rd index 7d2ba00..2dc8d97 100644 --- a/man/dropDeadEdges.Rd +++ b/man/dropDeadEdges.Rd @@ -28,9 +28,8 @@ Dead nodes are nodes that are not connected to any other node, thus not having any role in the connectivity of a graph.\cr } \examples{ - \dontrun{ -plot(worldgraph.10k,reset=TRUE) +plot(worldgraph.10k, reset = TRUE) x <- dropDeadNodes(worldgraph.10k) plot(x) } diff --git a/man/extractFromLayer.Rd b/man/extractFromLayer.Rd index 08fb2ed..c92db67 100644 --- a/man/extractFromLayer.Rd +++ b/man/extractFromLayer.Rd @@ -67,30 +67,22 @@ Nodes can be specified in different ways, including by providing a input formats. } \examples{ - \dontrun{ -plot(worldgraph.10k, reset=TRUE) - - -## see what info is available -names(worldshape@data) -unique(worldshape@data$CONTINENT) - +plot(worldgraph.10k, reset = TRUE) ## retrieve continent info for all nodes ## (might take a few seconds) -x <- extractFromLayer(worldgraph.10k, layer=worldshape, attr="CONTINENT") +x <- extractFromLayer(worldgraph.10k, layer = "world", attr = "CONTINENT") x -table(getNodesAttr(x, attr.name="CONTINENT")) +table(getNodesAttr(x, attr.name = "CONTINENT")) ## subset Africa -temp <- getNodesAttr(x, attr.name="CONTINENT")=="Africa" +temp <- getNodesAttr(x, attr.name = "CONTINENT") == "Africa" temp[is.na(temp)] <- FALSE x <- x[temp] -plot(x, reset=TRUE) - +plot(x, reset = TRUE) } } diff --git a/man/findLand.Rd b/man/findLand.Rd index cc298ea..a513acd 100644 --- a/man/findLand.Rd +++ b/man/findLand.Rd @@ -55,8 +55,8 @@ Nodes can be specified either as a matrix of geographic coordinates, or as a ## create a new gGraph with random coordinates -myCoords <- data.frame(long=runif(1000,-180,180), lat=runif(1000,-90,90)) -obj <- new("gGraph", coords=myCoords) +myCoords <- data.frame(long = runif(1000, -180, 180), lat = runif(1000, -90, 90)) +obj <- new("gGraph", coords = myCoords) obj # note: no node attribute plot(obj) @@ -65,14 +65,13 @@ obj <- findLand(obj) obj # note: new node attribute ## define rules for colors -temp <- data.frame(habitat=c("land","sea"), color=c("green","blue")) +temp <- data.frame(habitat = c("land", "sea"), color = c("green", "blue")) temp obj@meta$color <- temp ## plot object with new colors plot(obj) - } \seealso{ \code{\link{extractFromLayer}}, to retrieve any information from a diff --git a/man/gData-class.Rd b/man/gData-class.Rd index 42deaf9..fcd8fb7 100644 --- a/man/gData-class.Rd +++ b/man/gData-class.Rd @@ -63,16 +63,15 @@ arguments: hgdp ## plot data -plot(worldgraph.40k, pch="") +plot(worldgraph.40k, pch = "") points(hgdp) ## subset and plot data -onlyNorth <- hgdp[hgdp@data$Latitude >0] # only northern populations - -plot(worldgraph.40k, reset=TRUE) -abline(h=0) # equator -points(onlyNorth, pch.node=20, cex=2, col.node="purple") +onlyNorth <- hgdp[hgdp@data$Latitude > 0] # only northern populations +plot(worldgraph.40k, reset = TRUE) +abline(h = 0) # equator +points(onlyNorth, pch.node = 20, cex = 2, col.node = "purple") } \seealso{ diff --git a/man/gGraph-class.Rd b/man/gGraph-class.Rd index dde6eab..ec782b8 100644 --- a/man/gGraph-class.Rd +++ b/man/gGraph-class.Rd @@ -65,10 +65,10 @@ new("gGraph") ## plotting the object -plot(rawgraph.10k, reset=TRUE) +plot(rawgraph.10k, reset = TRUE) ## zooming in -geo.zoomin(list(x=c(-6,38), y=c(35,73))) +geo.zoomin(list(x = c(-6, 38), y = c(35, 73))) title("Europe") ## to play interactively with graphics, use: @@ -79,20 +79,19 @@ title("Europe") ## defining a new object restrained to visible nodes x <- rawgraph.10k[isInArea(rawgraph.10k)] -plot(x,reset=TRUE, edges=TRUE) +plot(x, reset = TRUE, edges = TRUE) title("x does just contain these visible nodes.") ## define weights for edges -x <- setCosts(x, attr.name="habitat", method="prod") -plot(x,edges=TRUE) +x <- setCosts(x, attr.name = "habitat", method = "prod") +plot(x, edges = TRUE) title("costs defined by habitat (land/land=1, other=100)") ## drop 'dead edges' (i.e. with weight 0) -x <- dropDeadEdges(x, thres=10) -plot(x,edges=TRUE) +x <- dropDeadEdges(x, thres = 10) +plot(x, edges = TRUE) title("after droping edges with null weight") - } \seealso{ Related classes are:\cr \% - \code{\linkS4class{graphNEL}} diff --git a/man/geo.add.edges.Rd b/man/geo.add.edges.Rd index 4d90b58..9197a72 100644 --- a/man/geo.add.edges.Rd +++ b/man/geo.add.edges.Rd @@ -33,21 +33,20 @@ edges (mode="points")\cr - select an area in which all edges from a reference graph are added (mode="area").\cr } \examples{ - \dontrun{ -plot(worldgraph.10k, reset=TRUE) +plot(worldgraph.10k, reset = TRUE) ## zooming in -geo.zoomin(list(x=c(-6,38), y=c(35,73))) +geo.zoomin(list(x = c(-6, 38), y = c(35, 73))) title("Europe") ## remove edges geo.remove.edges(worldgraph.10k) # points mode -geo.remove.edges(worldgraph.10k, mode="area") # area mode +geo.remove.edges(worldgraph.10k, mode = "area") # area mode ## add edges geo.add.edges(worldgraph.10k) # points mode -geo.add.edges(worldgraph.10k, mode="area") # area mode +geo.add.edges(worldgraph.10k, mode = "area") # area mode } } \seealso{ diff --git a/man/geo.change.attr.Rd b/man/geo.change.attr.Rd index 66e94b7..8c3eb7e 100644 --- a/man/geo.change.attr.Rd +++ b/man/geo.change.attr.Rd @@ -60,23 +60,22 @@ worldgraph.10k that are exclusively on land: this would be done by specifying \code{only.name="habitat"} and \code{only.value="land"}. } \examples{ - \dontrun{ -plot(worldgraph.10k, reset=TRUE) +plot(worldgraph.10k, reset = TRUE) ## have to click here for an area ## all nodes are modified in the area -x <- geo.change.attr(worldgraph.10k, mode="area", attr.name="habitat", attr.value="fancy -habitat", newCol="pink") # modify selected area +x <- geo.change.attr(worldgraph.10k, mode = "area", attr.name = "habitat", attr.value = "fancy +habitat", newCol = "pink") # modify selected area -plot(x,reset=TRUE) # modification in the whole selected area +plot(x, reset = TRUE) # modification in the whole selected area ## have to click here for an area ## only nodes on land are modified -x <- geo.change.attr(x, mode="area", attr.name="habitat", attr.value="fancy2 -habitat", newCol="purple", only.name="habitat", only.value="land") +x <- geo.change.attr(x, mode = "area", attr.name = "habitat", attr.value = "fancy2 +habitat", newCol = "purple", only.name = "habitat", only.value = "land") -plot(x,reset=TRUE) # modification in the whole selected area +plot(x, reset = TRUE) # modification in the whole selected area } } diff --git a/man/geoGraph-package.Rd b/man/geoGraph-package.Rd index a01dd39..3b888b3 100644 --- a/man/geoGraph-package.Rd +++ b/man/geoGraph-package.Rd @@ -89,10 +89,10 @@ To cite geoGraph, please use the reference given by worldgraph.10k ## plotting the object -plot(worldgraph.10k, reset=TRUE) +plot(worldgraph.10k, reset = TRUE) ## zooming in -geo.zoomin(list(x=c(-6,38), y=c(35,73))) +geo.zoomin(list(x = c(-6, 38), y = c(35, 73))) title("Europe") ## to play interactively with graphics, use: @@ -103,20 +103,19 @@ title("Europe") ## defining a new object restrained to visible nodes x <- worldgraph.10k[isInArea(worldgraph.10k)] -plot(x,reset=TRUE, edges=TRUE) +plot(x, reset = TRUE, edges = TRUE) title("x does just contain these visible nodes.") ## define weights for edges -x <- setCosts(x, attr.name="habitat", method="prod") -plot(x,edges=TRUE) +x <- setCosts(x, attr.name = "habitat", method = "prod") +plot(x, edges = TRUE) title("connectivity defined by habitat (land/land=1, other=0)") ## drop 'dead edges' (i.e. with weight 0) x <- dropDeadEdges(x) -plot(x,edges=TRUE) +plot(x, edges = TRUE) title("after droping edges with null weight") - } \keyword{manip} \keyword{spatial} diff --git a/man/getColors.Rd b/man/getColors.Rd index 03da00a..7eca63f 100644 --- a/man/getColors.Rd +++ b/man/getColors.Rd @@ -55,8 +55,7 @@ worldgraph.10k # there is a node attribute 'habitat' worldgraph.10k@meta$color head(getNodes(worldgraph.10k)) -head(getColors(worldgraph.10k,res.type="vector", attr.name="habitat")) - +head(getColors(worldgraph.10k, res.type = "vector", attr.name = "habitat")) } \author{ diff --git a/man/getCosts.Rd b/man/getCosts.Rd index 41d103e..0d6df6d 100644 --- a/man/getCosts.Rd +++ b/man/getCosts.Rd @@ -66,8 +66,8 @@ connectivity there is between the couple of concerned nodes. }} \examples{ -head(getEdges(worldgraph.10k, res.type="matNames",unique=TRUE)) -head(getCosts(worldgraph.10k,res.type="vector",unique=TRUE)) +head(getEdges(worldgraph.10k, res.type = "matNames", unique = TRUE)) +head(getCosts(worldgraph.10k, res.type = "vector", unique = TRUE)) } diff --git a/man/getEdges.Rd b/man/getEdges.Rd index 0f9b22d..2e6dfa7 100644 --- a/man/getEdges.Rd +++ b/man/getEdges.Rd @@ -47,8 +47,8 @@ object using different possible outputs. example(gGraph) getEdges(x) -getEdges(x,res.type="matNames") -getEdges(x,res.type="matId") +getEdges(x, res.type = "matNames") +getEdges(x, res.type = "matId") } \seealso{ diff --git a/man/getNodesAttr.Rd b/man/getNodesAttr.Rd index 22167cf..737cea1 100644 --- a/man/getNodesAttr.Rd +++ b/man/getNodesAttr.Rd @@ -50,7 +50,6 @@ head(getNodesAttr(worldgraph.40k)) ## gData method getNodesAttr(hgdp) - } \seealso{ Most other accessors are documented in \linkS4class{gGraph} and diff --git a/man/hgdp.Rd b/man/hgdp.Rd index 8a0c986..32341f9 100644 --- a/man/hgdp.Rd +++ b/man/hgdp.Rd @@ -37,24 +37,24 @@ plot(hgdp) ## results from Handley et al. \dontrun{ ## Addis Ababa -addis <- list(lon=38.74,lat=9.03) -addis <- closestNode(worldgraph.40k,addis) # this takes a while +addis <- list(lon = 38.74, lat = 9.03) +addis <- closestNode(worldgraph.40k, addis) # this takes a while ## shortest path from Addis Ababa myPath <- dijkstraFrom(hgdp, addis) ## plot results -plot(worldgraph.40k, col=0) +plot(worldgraph.40k, col = 0) points(hgdp) -points(worldgraph.40k[addis], psize=3,pch="x", col="black") +points(worldgraph.40k[addis], psize = 3, pch = "x", col = "black") plot(myPath) ## correlations distance/genetic div. -geo.dist <- sapply(myPath[-length(myPath)],function(e) e$length) -gen.div <- getData(hgdp)[,"Genetic.Div"] -plot(gen.div~geo.dist) -lm1 <- lm(gen.div~geo.dist) -abline(lm1, col="blue") # this regression is wrong +geo.dist <- sapply(myPath[-length(myPath)], function(e) e$length) +gen.div <- getData(hgdp)[, "Genetic.Div"] +plot(gen.div ~ geo.dist) +lm1 <- lm(gen.div ~ geo.dist) +abline(lm1, col = "blue") # this regression is wrong summary(lm1) } diff --git a/man/isInArea.Rd b/man/isInArea.Rd index c8a5186..3f78143 100644 --- a/man/isInArea.Rd +++ b/man/isInArea.Rd @@ -89,10 +89,10 @@ the output are also available. }} \examples{ -plot(worldgraph.10k, reset=TRUE) +plot(worldgraph.10k, reset = TRUE) ## zooming in -geo.zoomin(list(x=c(-6,38), y=c(35,73))) +geo.zoomin(list(x = c(-6, 38), y = c(35, 73))) title("Europe") @@ -102,14 +102,14 @@ length(isInArea(worldgraph.10k)) sum(isInArea(worldgraph.10k)) head(which(isInArea(worldgraph.10k))) # which nodes are TRUE ? -head(isInArea(worldgraph.10k, res.type="integer")) # node indices +head(isInArea(worldgraph.10k, res.type = "integer")) # node indices -head(isInArea(worldgraph.10k, res.type="character")) # node names +head(isInArea(worldgraph.10k, res.type = "character")) # node names ## use isInArea to have a subset of visible nodes x <- worldgraph.10k[isInArea(worldgraph.10k)] -plot(x, reset=TRUE) +plot(x, reset = TRUE) } \author{ diff --git a/man/makeGrid.Rd b/man/makeGrid.Rd index c0057d2..73c57a8 100644 --- a/man/makeGrid.Rd +++ b/man/makeGrid.Rd @@ -39,18 +39,20 @@ curvature of the surface of the earth can be neglected. ## zoom in to a smaller area plot(worldgraph.10k) -geo.zoomin(c(-10,0, 50,54)) +geo.zoomin(c(-10, 0, 50, 54)) ## make a new gGraph newGraph <- makeGrid(1e3) newGraph <- findLand(newGraph) -newGraph@meta$colors <- data.frame(habitat=c("sea","land"), -color=c("blue","green")) +newGraph@meta$colors <- data.frame( + habitat = c("sea", "land"), + color = c("blue", "green") +) ## plot the new gGraph -plot(newGraph, reset=TRUE, edge=TRUE) +plot(newGraph, reset = TRUE, edge = TRUE) } \author{ diff --git a/man/pipe.Rd b/man/pipe.Rd new file mode 100644 index 0000000..a648c29 --- /dev/null +++ b/man/pipe.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils-pipe.R +\name{\%>\%} +\alias{\%>\%} +\title{Pipe operator} +\usage{ +lhs \%>\% rhs +} +\arguments{ +\item{lhs}{A value or the magrittr placeholder.} + +\item{rhs}{A function call using the magrittr semantics.} +} +\value{ +The result of calling \code{rhs(lhs)}. +} +\description{ +See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. +} +\keyword{internal} diff --git a/man/plot-gData.Rd b/man/plot-gData.Rd index 7d7d08e..6b2675f 100644 --- a/man/plot-gData.Rd +++ b/man/plot-gData.Rd @@ -89,26 +89,25 @@ the \code{gData} plot.\cr \examples{ -myLoc <- list(x=c(3, -8, 11, 28), y=c(50, 57, 71, 67)) # some locations -obj <- new("gData", coords=myLoc) # new gData object +myLoc <- list(x = c(3, -8, 11, 28), y = c(50, 57, 71, 67)) # some locations +obj <- new("gData", coords = myLoc) # new gData object obj obj@gGraph.name <- "worldgraph.10k" -obj <- closestNode(obj, attr.name="habitat", attr.value="land") +obj <- closestNode(obj, attr.name = "habitat", attr.value = "land") ## plot the result (original location -> assigned node) -plot(obj, type="both",reset=TRUE) +plot(obj, type = "both", reset = TRUE) title("'x'=location, 'o'=assigned node") ## using different parameters -points(obj, type="both", pch.ori=2, col.ori="red", pch.nodes=20, col.nodes="pink") +points(obj, type = "both", pch.ori = 2, col.ori = "red", pch.nodes = 20, col.nodes = "pink") ## only nodes, fancy plot -plot(obj, col.nodes="red", cex=1, pch.node=20) -points(obj, col.nodes="red", cex=2) -points(obj, col.nodes="orange", cex=3) -points(obj, col.nodes="yellow", cex=4) - +plot(obj, col.nodes = "red", cex = 1, pch.node = 20) +points(obj, col.nodes = "red", cex = 2) +points(obj, col.nodes = "orange", cex = 3) +points(obj, col.nodes = "yellow", cex = 4) } \seealso{ diff --git a/man/plot-gGraph.Rd b/man/plot-gGraph.Rd index 5444c7f..f181cca 100644 --- a/man/plot-gGraph.Rd +++ b/man/plot-gGraph.Rd @@ -88,32 +88,31 @@ specify \code{reset=TRUE} as argument to \code{plot}. ## just the background -plot(worldgraph.10k,reset=TRUE,type="n") +plot(worldgraph.10k, reset = TRUE, type = "n") ## basic plot plot(worldgraph.10k) ## zooming and adding edges -geo.zoomin(list(x=c(90,150),y=c(0,-50))) -plot(worldgraph.10k, edges=TRUE) +geo.zoomin(list(x = c(90, 150), y = c(0, -50))) +plot(worldgraph.10k, edges = TRUE) ## display edges differently -plotEdges(worldgraph.10k, col="red", lwd=2) +plotEdges(worldgraph.10k, col = "red", lwd = 2) ## replot points with different color -points(worldgraph.10k, col="orange") +points(worldgraph.10k, col = "orange") ## mask points in the sea -inSea <- unlist(getNodesAttr(worldgraph.10k,attr.name="habitat"))=="sea" +inSea <- unlist(getNodesAttr(worldgraph.10k, attr.name = "habitat")) == "sea" head(inSea) -points(worldgraph.10k[inSea], col="white", sticky=TRUE) # this will stay +points(worldgraph.10k[inSea], col = "white", sticky = TRUE) # this will stay ## but better, only draw those on land, and use a fancy setup -par(bg="blue") -plot(worldgraph.10k[!inSea], bg.col="darkgreen", col="purple", edges=TRUE) - +par(bg = "blue") +plot(worldgraph.10k[!inSea], bg.col = "darkgreen", col = "purple", edges = TRUE) } \seealso{ diff --git a/man/setCosts.Rd b/man/setCosts.Rd index 0cbf3ca..f6bcef6 100644 --- a/man/setCosts.Rd +++ b/man/setCosts.Rd @@ -43,21 +43,20 @@ Also note that 'costs' defined in \code{geoGraph} are equivalent to } \examples{ -plot(rawgraph.10k, reset=TRUE) +plot(rawgraph.10k, reset = TRUE) ## zooming in -geo.zoomin(list(x=c(-6,38), y=c(35,73))) +geo.zoomin(list(x = c(-6, 38), y = c(35, 73))) title("Europe") ## defining a new object restrained to visible nodes x <- rawgraph.10k[isInArea(rawgraph.10k)] ## define weights for edges -x <- setCosts(x, attr.name="habitat") -plot(x,edges=TRUE) +x <- setCosts(x, attr.name = "habitat") +plot(x, edges = TRUE) title("costs defined by habitat (land/land=1, other=100)") - } \seealso{ \code{\link{dropDeadEdges}}, to get rid of edge whose cost is below diff --git a/man/setDistCosts.Rd b/man/setDistCosts.Rd index 8e31a19..1005258 100644 --- a/man/setDistCosts.Rd +++ b/man/setDistCosts.Rd @@ -40,19 +40,19 @@ connectivity there is between the couple of concerned nodes. }} \examples{ -if(require(fields)){ -## load data -plot(rawgraph.10k,reset=TRUE) -geo.zoomin(list(x=c(110,150),y=c(-10,-40))) -plotEdges(rawgraph.10k) +if (require(fields)) { + ## load data + plot(rawgraph.10k, reset = TRUE) + geo.zoomin(list(x = c(110, 150), y = c(-10, -40))) + plotEdges(rawgraph.10k) -## compute costs -x <- rawgraph.10k[isInArea(rawgraph.10k)] -x <- setDistCosts(x) + ## compute costs + x <- rawgraph.10k[isInArea(rawgraph.10k)] + x <- setDistCosts(x) -## replot edges -plotEdges(x) # no big differences can be seen -head(getCosts(x)) + ## replot edges + plotEdges(x) # no big differences can be seen + head(getCosts(x)) } } diff --git a/man/worldgraph.Rd b/man/worldgraph.Rd index 5b91620..4ae5fc9 100644 --- a/man/worldgraph.Rd +++ b/man/worldgraph.Rd @@ -30,10 +30,10 @@ world, with respective resolutions of 10,242 and 40,962 vertices.\cr references.\cr 'worldgraph's are 'rawgraph's that have been modified manually to rectify -connectivity between edges at some places. The most noticable change is that +connectivity between edges at some places. The most noticeable change is that all edges involving sea vertices have been removed.\cr -'worldshape' is a shapefile of contries of the world (snapshot from 1994). +'worldshape' is a shapefile of countries of the world (snapshot from 1994). } \examples{ @@ -41,24 +41,24 @@ all edges involving sea vertices have been removed.\cr worldgraph.10k ## plotting the object -plot(worldgraph.10k, reset=TRUE) +plot(worldgraph.10k, reset = TRUE) title("Hello world") ## zooming in -geo.zoomin(list(x=c(-12,45), y=c(33,75))) +geo.zoomin(list(x = c(-12, 45), y = c(33, 75))) title("Europe") -geo.zoomin(list(x=c(-12,2), y=c(50,60))) +geo.zoomin(list(x = c(-12, 2), y = c(50, 60))) plotEdges(worldgraph.10k) title("United Kingdom") ## zooming out # geo.zoomout() # needs clicking on device -geo.zoomin(list(x=c(-6,38), y=c(35,73))) +geo.zoomin(list(x = c(-6, 38), y = c(35, 73))) title("Europe") ## defining the subset of visible points x <- worldgraph.10k[isInArea(worldgraph.10k)] -plot(x,reset=TRUE, edges=TRUE) +plot(x, reset = TRUE, edges = TRUE) title("One subsetted object.") \dontrun{ @@ -66,7 +66,6 @@ title("One subsetted object.") geo.zoomin() } - } \references{ === On the construction of the graph ===\cr Randall, D. A.; diff --git a/man/zoom.Rd b/man/zoom.Rd index 0eda369..c5b66cf 100644 --- a/man/zoom.Rd +++ b/man/zoom.Rd @@ -50,16 +50,15 @@ Whenever clicking is needed, a right-click will stop the function. } \examples{ -plot(worldgraph.10k, reset=TRUE) +plot(worldgraph.10k, reset = TRUE) ## zooming in -x.ini <- c(-100,-60) -y.ini <- c(-30,30) -for(i in 0:3){ -geo.zoomin(list(x=x.ini + i*60, y=y.ini)) +x.ini <- c(-100, -60) +y.ini <- c(-30, 30) +for (i in 0:3) { + geo.zoomin(list(x = x.ini + i * 60, y = y.ini)) } - \dontrun{ ## going back geo.back() # you have to click ! From 45e1aabd37ec9dacf479598b65bead77c972fe44 Mon Sep 17 00:00:00 2001 From: m-colucci Date: Tue, 5 Dec 2023 14:31:08 +0100 Subject: [PATCH 14/19] update column checks --- R/classes.R | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/R/classes.R b/R/classes.R index fff4b82..29f3063 100644 --- a/R/classes.R +++ b/R/classes.R @@ -281,18 +281,20 @@ setMethod("initialize", "gGraph", function(.Object, ...) { ## handle @coords ## if (!is.null(input$coords)) { - if (is.list(input$coords) && length(input$coords) > 2) { - stop("Argument coords must include only two columns (longitude and latitude).") - } - if (is.list(input$coords) && length(input$coords) == 2) { + + if (is.list(input$coords)) { input$coords <- as.data.frame(input$coords) } if (is.data.frame(input$coords)) { input$coords <- as.matrix(input$coords) } - + + if (ncol(input$coords)!=2){ + stop("Argument coords must include only two columns (longitude and latitude).") + } + if (nrow(input$coords) > 0 && !is.numeric(input$coords)) { stop("Argument coords has to be numeric.") } From 7fea0240541fbe93b3f6d2d6d2bfe7492c965077 Mon Sep 17 00:00:00 2001 From: Aramish Fatima Date: Wed, 6 Dec 2023 23:45:44 +0000 Subject: [PATCH 15/19] Added column name swap and test for column names --- R/classes.R | 4 ++++ tests/testthat/test_classes.R | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/R/classes.R b/R/classes.R index 29f3063..78ea285 100644 --- a/R/classes.R +++ b/R/classes.R @@ -304,6 +304,10 @@ setMethod("initialize", "gGraph", function(.Object, ...) { stop("Argument coords includes NAs") } + if (identical(colnames(input$coords), c("lat", "lon"))) { + input$coords[ , c(1,2)] <- input$coords[ , c(2,1)] + } + ## names of the matrix colnames(input$coords) <- c("lon", "lat") diff --git a/tests/testthat/test_classes.R b/tests/testthat/test_classes.R index d6c0513..a9f5ca3 100644 --- a/tests/testthat/test_classes.R +++ b/tests/testthat/test_classes.R @@ -29,3 +29,15 @@ test_that("Contructors fails with invalid non-numeric matrix",{ "Argument coords has to be numeric") }) + +test_that("Constructor checks column headings" , { + column_heading <- data.frame(lat = c(-24, 37), lon = c(31,55)) + #Create Ggraph with lat/lon headings + correct_heading <- new("gGraph", coords = column_heading) + column_heading <- data.frame(lon = c(31,55), lat = c(-24, 37)) + #Create Ggraph with lon/lat headings + swapped_heading <- new("gGraph", coords = column_heading) + expect_identical(correct_heading, swapped_heading, + "Argument column names are not recognised") +}) + From 7c220c9a811788daa041e8128849f4c73ae1de08 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Tue, 12 Dec 2023 14:02:09 +0000 Subject: [PATCH 16/19] Add simple test to extractFromLayer --- R/extractFromLayer.R | 2 ++ tests/testthat/test_extractFromLayer.R | 8 ++++++++ 2 files changed, 10 insertions(+) create mode 100644 tests/testthat/test_extractFromLayer.R diff --git a/R/extractFromLayer.R b/R/extractFromLayer.R index 6d3a3e7..9207da9 100644 --- a/R/extractFromLayer.R +++ b/R/extractFromLayer.R @@ -105,6 +105,7 @@ setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all } } + ## search attr in data ## if (attr[1] == "all") { selAttr <- 1:ncol(layer@data) @@ -150,6 +151,7 @@ setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all } # end for j } # end for i + # @TOFIX the line below will fail if layerId is all NAs (i.e. no points were assigned to a polygon) res <- dat[layerId, selAttr, drop = FALSE] row.names(res) <- rownames(x) diff --git a/tests/testthat/test_extractFromLayer.R b/tests/testthat/test_extractFromLayer.R new file mode 100644 index 0000000..b0cad72 --- /dev/null +++ b/tests/testthat/test_extractFromLayer.R @@ -0,0 +1,8 @@ +test_that("extractFromLayer assigns points correctly", + { + # create a matrix of locations including two continents and the sea + myCoords <- data.frame(long = c(-24, 71.5, -46.5), lat = c(31, 30,-23.5)) + # assign to continents + continents <- extractFromLayer(myCoords, layer = worldshape, attr = "CONTINENT") + expect_identical(as.character(continents$CONTINENT), c(NA,"Asia","South America")) + }) \ No newline at end of file From e5598c634aac2546ae82314e5cd8c6f96aff012f Mon Sep 17 00:00:00 2001 From: Aramish Fatima Date: Tue, 19 Dec 2023 00:20:00 +0000 Subject: [PATCH 17/19] Added code to account for different lon/lat spelling and capitalisation --- R/classes.R | 26 ++++++++++++++++++++++++-- tests/testthat/test_classes.R | 17 ++++++++++++++++- tests/testthat/test_findLand.R | 2 +- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/R/classes.R b/R/classes.R index 78ea285..abf72b1 100644 --- a/R/classes.R +++ b/R/classes.R @@ -304,8 +304,30 @@ setMethod("initialize", "gGraph", function(.Object, ...) { stop("Argument coords includes NAs") } - if (identical(colnames(input$coords), c("lat", "lon"))) { - input$coords[ , c(1,2)] <- input$coords[ , c(2,1)] + ## Convert all column names to lower case + colnames(input$coords) <- tolower(colnames(input$coords)) + ## Create list of lon/lat column heading names + lonlist <- list("lon", "longitude", "x") + latlist <- list("lat", "latitude", "y") + ## Test first column name against list + if (is.element(colnames(input$coords)[1], lonlist)) { + reverse_column = FALSE + } else if (is.element(colnames(input$coords)[1], latlist)) { + reverse_column = TRUE + } else { + stop("Argument first column name not recognised") + } + ## Test second column name against list + if (is.element(colnames(input$coords)[2], latlist)) { + reverse_column = FALSE + } else if (is.element(colnames(input$coords)[2], lonlist)) { + reverse_column = TRUE + } else { + stop("Argument second column name not recognised") + } + + if (reverse_column) { + input$coords[, c(1, 2)] <- input$coords[, c(2, 1)] } diff --git a/tests/testthat/test_classes.R b/tests/testthat/test_classes.R index a9f5ca3..f54ea72 100644 --- a/tests/testthat/test_classes.R +++ b/tests/testthat/test_classes.R @@ -30,6 +30,22 @@ test_that("Contructors fails with invalid non-numeric matrix",{ }) + + +test_that("Constructor accounts for different column names" , { + columnheading_names <- + data.frame(longitude = c(31, 55), Latitude = c(-24, 37)) + columnheading_names <- new("gGraph", coords = columnheading_names) + new_columnheading_names <- + data.frame(lon = c(31, 55), lat = c(-24, 37)) + new_columnheading_names <- + new("gGraph", coords = new_columnheading_names) + expect_identical(columnheading_names, + new_columnheading_names, + "Argument column names not listed") + +}) + test_that("Constructor checks column headings" , { column_heading <- data.frame(lat = c(-24, 37), lon = c(31,55)) #Create Ggraph with lat/lon headings @@ -40,4 +56,3 @@ test_that("Constructor checks column headings" , { expect_identical(correct_heading, swapped_heading, "Argument column names are not recognised") }) - diff --git a/tests/testthat/test_findLand.R b/tests/testthat/test_findLand.R index a8c85d2..17af0be 100644 --- a/tests/testthat/test_findLand.R +++ b/tests/testthat/test_findLand.R @@ -1,6 +1,6 @@ test_that("find land correctly",{ # create a gGraph with one sea node and one land node - myCoords <- data.frame(long = c(-24, 37), lat = c(31,55)) + myCoords <- data.frame(lon = c(-24, 37), lat = c(31,55)) obj <- new("gGraph", coords = myCoords) obj <- findLand(obj) # check that we classified the nodes correctly From 034288037033436ebad4ed41aeaf9259d82ab097 Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Tue, 19 Dec 2023 09:16:41 +0000 Subject: [PATCH 18/19] Simplify column name checks --- R/classes.R | 28 ++++++++-------------------- tests/testthat/test_classes.R | 22 +++++++++++++++++----- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/R/classes.R b/R/classes.R index abf72b1..f54805e 100644 --- a/R/classes.R +++ b/R/classes.R @@ -309,27 +309,15 @@ setMethod("initialize", "gGraph", function(.Object, ...) { ## Create list of lon/lat column heading names lonlist <- list("lon", "longitude", "x") latlist <- list("lat", "latitude", "y") - ## Test first column name against list - if (is.element(colnames(input$coords)[1], lonlist)) { - reverse_column = FALSE - } else if (is.element(colnames(input$coords)[1], latlist)) { - reverse_column = TRUE - } else { - stop("Argument first column name not recognised") - } - ## Test second column name against list - if (is.element(colnames(input$coords)[2], latlist)) { - reverse_column = FALSE - } else if (is.element(colnames(input$coords)[2], lonlist)) { - reverse_column = TRUE - } else { - stop("Argument second column name not recognised") - } - - if (reverse_column) { + ## Test if the column order is inverted + if (is.element(colnames(input$coords)[1], latlist) & + is.element(colnames(input$coords)[2], lonlist)) { input$coords[, c(1, 2)] <- input$coords[, c(2, 1)] - } - + } else if (!(is.element(colnames(input$coords)[1], lonlist) & + is.element(colnames(input$coords)[2], latlist))){ + message("The coordinate column names are not part of the standardised list;\n", + "we will use the order they were given in, make sure it corresponds to x and y!") + } # if neither of the if catches it, then the names are part of the lists and in the correct order ## names of the matrix colnames(input$coords) <- c("lon", "lat") diff --git a/tests/testthat/test_classes.R b/tests/testthat/test_classes.R index f54ea72..986a855 100644 --- a/tests/testthat/test_classes.R +++ b/tests/testthat/test_classes.R @@ -41,18 +41,30 @@ test_that("Constructor accounts for different column names" , { new_columnheading_names <- new("gGraph", coords = new_columnheading_names) expect_identical(columnheading_names, - new_columnheading_names, - "Argument column names not listed") + new_columnheading_names) }) -test_that("Constructor checks column headings" , { +test_that("Constructor reverses coord column order" , { column_heading <- data.frame(lat = c(-24, 37), lon = c(31,55)) #Create Ggraph with lat/lon headings correct_heading <- new("gGraph", coords = column_heading) column_heading <- data.frame(lon = c(31,55), lat = c(-24, 37)) #Create Ggraph with lon/lat headings swapped_heading <- new("gGraph", coords = column_heading) - expect_identical(correct_heading, swapped_heading, - "Argument column names are not recognised") + expect_identical(correct_heading, swapped_heading) }) + +test_that("we give message when columns are not recognised",{ + column_heading <- data.frame(lon= c(31,55), lat = c(-24, 37)) + #Create Ggraph with lat/lon headings + correct_heading <- new("gGraph", coords = column_heading) + column_heading <- data.frame(blah= c(31,55), lat = c(-24, 37)) + #Create Ggraph with lon/lat headings + expect_message(unrecognised_heading <- new("gGraph", coords = column_heading), + "The coordinate column names are not part of the standardised list") + expect_identical(correct_heading, unrecognised_heading) +} + + + ) From 03197d4e2a92c8e904e334355d8ee6ad8522626a Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Tue, 19 Dec 2023 13:20:26 +0000 Subject: [PATCH 19/19] Add long to accepted labels --- R/classes.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/classes.R b/R/classes.R index f54805e..90db994 100644 --- a/R/classes.R +++ b/R/classes.R @@ -307,7 +307,7 @@ setMethod("initialize", "gGraph", function(.Object, ...) { ## Convert all column names to lower case colnames(input$coords) <- tolower(colnames(input$coords)) ## Create list of lon/lat column heading names - lonlist <- list("lon", "longitude", "x") + lonlist <- list("lon", "long", "longitude", "x") latlist <- list("lat", "latitude", "y") ## Test if the column order is inverted if (is.element(colnames(input$coords)[1], latlist) &