diff --git a/DESCRIPTION b/DESCRIPTION index 537ce3a7..289a0b4b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: spdep -Version: 1.3-5 -Date: 2024-06-10 +Version: 1.3-6 +Date: 2024-06-11 Title: Spatial Dependence: Weighting Schemes, Statistics Encoding: UTF-8 Authors@R: c(person("Roger", "Bivand", role = c("cre", "aut"), diff --git a/NEWS.md b/NEWS.md index 8521f627..35e6359b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,8 @@ -# Version 1.3-5 (development) +# Version 1.3-6 (development) + +* add user interrupt to `n.comp.nb` #160 + +# Version 1.3-5 (2024-06-10) * #157 migrate ESRI Shapefile to GPKG files; convert bhicv.shp to GPKG diff --git a/R/components.R b/R/components.R index e81b73e6..1534a3b0 100644 --- a/R/components.R +++ b/R/components.R @@ -1,13 +1,33 @@ -# Copyright 2001 by Nicholas Lewin-Koh +# Copyright 2001 by Nicholas Lewin-Koh, igraph added RSB 2024 # -n.comp.nb <- function(nb.obj){ +n.comp.nb <- function(nb.obj, igraph=FALSE){ if(!inherits(nb.obj,"nb"))stop("not a neighbours list") - nb.obj <- make.sym.nb(nb.obj) - comp <- rep(0,length(nb.obj)) - comp <- .Call("g_components", nb.obj, as.integer(comp), PACKAGE="spdep") - answ <- list(nc=length(unique(comp)), comp.id=comp) + stopifnot(is.logical(igraph)) + stopifnot(length(igraph) == 1L) + nb.sym <- is.symmetric.nb(nb.obj) + if (igraph) { + if (!requireNamespace("igraph", quietly=TRUE)) { + igraph <- !igraph + warning("igraph not available, set FALSE") + } + } + if (!igraph) { + if (!nb.sym) nb.obj <- make.sym.nb(nb.obj) + comp <- rep(0,length(nb.obj)) + comp <- .Call("g_components", nb.obj, as.integer(comp), PACKAGE="spdep") + answ <- list(nc=length(unique(comp)), comp.id=comp) + } else { + stopifnot(requireNamespace("igraph", quietly=TRUE)) + stopifnot(requireNamespace("spatialreg", quietly=TRUE)) + B <- as(nb2listw(nb.obj, style="B", zero.policy=TRUE), "CsparseMatrix") + + g1 <- igraph::graph_from_adjacency_matrix(B, + mode=ifelse(nb.sym, "undirected", "directed")) + c1 <- igraph::components(g1, mode="weak") + answ <- list(nc=c1$no, comp.id=c1$membership) + } answ } diff --git a/man/compon.Rd b/man/compon.Rd index fe6c62d5..f2306191 100644 --- a/man/compon.Rd +++ b/man/compon.Rd @@ -1,4 +1,4 @@ -% Copyright 2001 by Roger S. Bivand and Nicholas Lewin-Koh +% Copyright 2001-24 by Roger S. Bivand and Nicholas Lewin-Koh \name{Graph Components} \alias{n.comp.nb} %\alias{reach.ij} @@ -8,11 +8,13 @@ \code{n.comp.nb()} finds the number of disjoint connected subgraphs in the graph depicted by \code{nb.obj} - a spatial neighbours list object. } \usage{ -n.comp.nb(nb.obj) +n.comp.nb(nb.obj, igraph=FALSE) } \arguments{ \item{nb.obj}{a neighbours list object of class \code{nb}} + \item{igraph}{default \code{FALSE}, if \code{TRUE} use \code{igraph::components} after converting the neighbour object to a sparse adjacency matrix then a graph} } +\details{If \code{igraph=TRUE} and \code{attr(nb.obj, "sym")} is \code{FALSE}, the components of the directed graph will be found by a simple breadth-first search; if \code{igraph=FALSE} and \code{attr(nb.obj, "sym")} is \code{FALSE}, the object will be made symmetric (which may be time-consuming with large numbers of neighbours) and the components found by depth-first search. If \code{igraph=TRUE} or \code{FALSE} and \code{attr(nb.obj, "sym")} is \code{TRUE}, the components of the directed graph will be found by depth-first search.} \value{ A list of: \item{nc}{number of disjoint connected subgraphs} @@ -32,11 +34,11 @@ table(res$comp.id) plot(col2, coords, add=TRUE) points(coords, col=res$comp.id, pch=16) run <- FALSE -if (require(igraph, quietly=TRUE) && require(spatialreg, quietly=TRUE)) run <- TRUE +if (require("igraph", quietly=TRUE) && require("spatialreg", quietly=TRUE)) run <- TRUE if (run) { B <- as(nb2listw(col2, style="B", zero.policy=TRUE), "CsparseMatrix") -g1 <- graph.adjacency(B, mode="undirected") -c1 <- clusters(g1) +g1 <- graph_from_adjacency_matrix(B, mode="undirected") +c1 <- components(g1) print(c1$no == res$nc) } if (run) { @@ -46,21 +48,17 @@ if (run) { print(all.equal(c1$csize, c(table(res$comp.id)), check.attributes=FALSE)) } if (run) { -W <- as(nb2listw(col2, style="W", zero.policy=TRUE), "CsparseMatrix") -g1W <- graph.adjacency(W, mode="directed", weighted="W") -c1W <- clusters(g1W) -print(all.equal(c1W$membership, res$comp.id, check.attributes=FALSE)) +resi <- n.comp.nb(col2, igraph=TRUE) +print(resi$nc == res$nc) } if (run) { -ow <- options("warn")$warn -options("warn"=2L) -# Matrix 1.4-2 vulnerability work-around -B1 <- try(get.adjacency(g1), silent=TRUE) -if (!inherits(B1, "try-error")) { -#B1 <- get.adjacency(g1) -print(all.equal(B, B1)) +print(all.equal(resi$comp.id, res$comp.id)) } -options("warn"=ow) +if (run) { +W <- as(nb2listw(col2, style="W", zero.policy=TRUE), "CsparseMatrix") +g1W <- graph_from_adjacency_matrix(W, mode="directed", weighted="W") +c1W <- components(g1W) +print(all.equal(c1W$membership, res$comp.id, check.attributes=FALSE)) } } diff --git a/man/lm.RStests.Rd b/man/lm.RStests.Rd index f93eec11..fc610f76 100644 --- a/man/lm.RStests.Rd +++ b/man/lm.RStests.Rd @@ -88,7 +88,7 @@ lw <- nb2listw(COL.nb) res <- lm.RStests(oldcrime.lm, listw=lw, test="all") summary(res) if (require("spatialreg", quietly=TRUE)) { - oldcrime.slx <- lm(CRIME ~ HOVAL + INC, data = COL.OLD, listw=lw) + oldcrime.slx <- lmSLX(CRIME ~ HOVAL + INC, data = COL.OLD, listw=lw) summary(lm.RStests(oldcrime.slx, listw=lw, test=c("adjRSerr", "adjRSlag"))) } } diff --git a/man/lm.morantest.exact.Rd b/man/lm.morantest.exact.Rd index d0c744fa..65643d66 100644 --- a/man/lm.morantest.exact.Rd +++ b/man/lm.morantest.exact.Rd @@ -54,7 +54,6 @@ must be one of greater (default), less or two.sided.} \examples{ eire <- st_read(system.file("shapes/eire.gpkg", package="spData")[1]) row.names(eire) <- as.character(eire$names) -st_crs(eire) <- "+proj=utm +zone=30 +ellps=airy +units=km" eire.nb <- poly2nb(eire) e.lm <- lm(OWNCONS ~ ROADACC, data=eire) lm.morantest(e.lm, nb2listw(eire.nb)) diff --git a/man/lm.morantest.sad.Rd b/man/lm.morantest.sad.Rd index 5aad56a7..fe457197 100644 --- a/man/lm.morantest.sad.Rd +++ b/man/lm.morantest.sad.Rd @@ -70,7 +70,6 @@ Geographical Analysis, 34, pp. 187--206; Bivand RS, Wong DWS 2018 Comparing impl \examples{ eire <- st_read(system.file("shapes/eire.gpkg", package="spData")[1]) row.names(eire) <- as.character(eire$names) -st_crs(eire) <- "+proj=utm +zone=30 +ellps=airy +units=km" eire.nb <- poly2nb(eire) e.lm <- lm(OWNCONS ~ ROADACC, data=eire) lm.morantest(e.lm, nb2listw(eire.nb)) diff --git a/man/mstree.Rd b/man/mstree.Rd index c1b57504..31724305 100644 --- a/man/mstree.Rd +++ b/man/mstree.Rd @@ -47,7 +47,6 @@ mstree(nbw, ini = NULL) ### loading data bh <- st_read(system.file("etc/shapes/bhicv.gpkg", package="spdep")[1], quiet=TRUE) -st_crs(bh) <- "OGC:CRS84" ### data padronized dpad <- data.frame(scale(as.data.frame(bh)[,5:8])) diff --git a/man/nblag.Rd b/man/nblag.Rd index 215f5c41..acc3ecbf 100644 --- a/man/nblag.Rd +++ b/man/nblag.Rd @@ -40,14 +40,14 @@ run <- FALSE if (require(igraph, quietly=TRUE) && require(spatialreg, quietly=TRUE)) run <- TRUE if (run) { W <- as(nb2listw(col.gal.nb), "CsparseMatrix") -G <- graph.adjacency(W, mode="directed", weight="W") +G <- graph_from_adjacency_matrix(W, mode="directed", weight="W") D <- diameter(G) nbs <- nblag(col.gal.nb, maxlag=D) n <- length(col.gal.nb) lmat <- lapply(nbs, nb2mat, style="B", zero.policy=TRUE) mat <- matrix(0, n, n) for (i in seq(along=lmat)) mat = mat + i*lmat[[i]] -G2 <- shortest.paths(G) +G2 <- distances(G) print(all.equal(G2, mat, check.attributes=FALSE)) } } diff --git a/man/skater.Rd b/man/skater.Rd index 3d8eb2d7..1db38d3c 100644 --- a/man/skater.Rd +++ b/man/skater.Rd @@ -74,7 +74,6 @@ skater(edges, data, ncuts, crit, vec.crit, method = c("euclidean", ### loading data bh <- st_read(system.file("etc/shapes/bhicv.gpkg", package="spdep")[1], quiet=TRUE) -st_crs(bh) <- "OGC:CRS84" ### data standardized dpad <- data.frame(scale(as.data.frame(bh)[,5:8])) diff --git a/src/dfs_ncomp.c b/src/dfs_ncomp.c index b44a8f33..17d5ec1e 100644 --- a/src/dfs_ncomp.c +++ b/src/dfs_ncomp.c @@ -1,4 +1,5 @@ -/* Copyright 2001 by Nicholas Lewin-Koh. */ +/* Copyright 2001 by Nicholas Lewin-Koh. + * interrupt added RSB 2024 */ #include "spdep.h" @@ -33,6 +34,7 @@ SEXP g_components(SEXP nblst, SEXP cmpnm){ } for(i=0; i < nvert; i++){ + R_CheckUserInterrupt(); if(INTEGER(visited)[i]==WHITE){ INTEGER(visited)[i]=BLACK; if(INTEGER(VECTOR_ELT(nblst,i))[0]==0){