nb object in spdep from categorical attribute

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

nb object in spdep from categorical attribute

Dexter Locke
Dear list,

Does anyone know how to make nb objects (to eventually make spatial
weights) with spdep using an attribute in a shapefile's data frame?

Consider, for example, all property parcels on the same street segment
should be defined as neighbors. In the parcel polygons I have the
associated street segment name.

KNN forces sparsely settled areas to become neighbors, which is undesirable
for the subsequent analyses.

Distances between parcels vary, so distance-based neighbors are also
undesirable in this case.

Contiguity-based methods do not connect parcels on opposite sites of the
same street segment.

Is there a way to use an attribute to define what constitutes a neighbor?

All ideas welcome,
Dexter

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: nb object in spdep from categorical attribute

Roger Bivand
Administrator
On Tue, 19 Jun 2018, Dexter Locke wrote:

> Dear list,
>
> Does anyone know how to make nb objects (to eventually make spatial
> weights) with spdep using an attribute in a shapefile's data frame?
>
> Consider, for example, all property parcels on the same street segment
> should be defined as neighbors. In the parcel polygons I have the
> associated street segment name.
>
> KNN forces sparsely settled areas to become neighbors, which is undesirable
> for the subsequent analyses.
>
> Distances between parcels vary, so distance-based neighbors are also
> undesirable in this case.
>
> Contiguity-based methods do not connect parcels on opposite sites of the
> same street segment.
>
> Is there a way to use an attribute to define what constitutes a neighbor?

Yes, spdep::nb2blocknb() is a specific case where say observations without
positional data are known to belong to an aggregate entity for which we
have positional data. The output is an nb object with diagonal blocks (if
the observations are sorted by block ID, not in the case below), as this
example shows. You'll need the development version to run it, as released
spdep::aggregate.nb() failed with empty aggregate sets - the nc median
poish grid has such empty sets:

# devtools::install.github("r-spatial/spdep")
library(spdep)
data(nc.sids)
ncCC89.nb[sapply(ncCC89.nb, length) == 0L] <- 0L
image(as(nb2listw(ncCC89.nb, zero.policy=TRUE), "CsparseMatrix"))
anb <- aggregate(ncCC89.nb, interaction(nc.sids$M.id, nc.sids$L.id))
image(as(nb2listw(anb, style="B"), "CsparseMatrix"))
# when the neighbour object is not empty
bnb <- nb2blocknb(anb, as.character(interaction(nc.sids$M.id,
   nc.sids$L.id)))
image(as(nb2listw(bnb, style="B"), "CsparseMatrix"))
# and when the neighbour object is empty
anb1 <- lapply(anb, function(x) x <- 0L)
attributes(anb1) <- attributes(anb)
bnb1 <- nb2blocknb(anb1, as.character(interaction(nc.sids$M.id,
   nc.sids$L.id)))
image(as(nb2listw(bnb1, style="B"), "CsparseMatrix"))

This isn't your case, but crafting an nb object by hand (adding
attributes after creating the list) then using spdep::union.nb or similar
to combine with a positional nb (such as poly2nb) may work. For parcels
across a stream or street, maybe look at the snap= argument if the streets
are narrower than frontages. Could you provide a small reproducible
example?

Hope this clarifies,

Roger

>
> All ideas welcome,
> Dexter
>
> [[alternative HTML version deleted]]
>
> _______________________________________________
> R-sig-Geo mailing list
> [hidden email]
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>

--
Roger Bivand
Department of Economics, Norwegian School of Economics,
Helleveien 30, N-5045 Bergen, Norway.
voice: +47 55 95 93 55; e-mail: [hidden email]
http://orcid.org/0000-0003-2392-6140
https://scholar.google.no/citations?user=AWeghB0AAAAJ&hl=en

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Roger Bivand
Department of Economics
Norwegian School of Economics
Helleveien 30
N-5045 Bergen, Norway
Reply | Threaded
Open this post in threaded view
|

Re: nb object in spdep from categorical attribute

Dexter Locke
Thanks so much.

The nb2blocknb(), aggregate.nb(), and union.nb() are fantastic functions!
Between these three functions I that I had not seen before I can accomplish
what I am seeking. It looks like the new spdep vignette has been greatly
expanded, which is also fantastic.

Thanks again,
Dexter


On Wed, Jun 20, 2018 at 8:24 AM Roger Bivand <[hidden email]> wrote:

> On Tue, 19 Jun 2018, Dexter Locke wrote:
>
> > Dear list,
> >
> > Does anyone know how to make nb objects (to eventually make spatial
> > weights) with spdep using an attribute in a shapefile's data frame?
> >
> > Consider, for example, all property parcels on the same street segment
> > should be defined as neighbors. In the parcel polygons I have the
> > associated street segment name.
> >
> > KNN forces sparsely settled areas to become neighbors, which is
> undesirable
> > for the subsequent analyses.
> >
> > Distances between parcels vary, so distance-based neighbors are also
> > undesirable in this case.
> >
> > Contiguity-based methods do not connect parcels on opposite sites of the
> > same street segment.
> >
> > Is there a way to use an attribute to define what constitutes a neighbor?
>
> Yes, spdep::nb2blocknb() is a specific case where say observations without
> positional data are known to belong to an aggregate entity for which we
> have positional data. The output is an nb object with diagonal blocks (if
> the observations are sorted by block ID, not in the case below), as this
> example shows. You'll need the development version to run it, as released
> spdep::aggregate.nb() failed with empty aggregate sets - the nc median
> poish grid has such empty sets:
>
> # devtools::install.github("r-spatial/spdep")
> library(spdep)
> data(nc.sids)
> ncCC89.nb[sapply(ncCC89.nb, length) == 0L] <- 0L
> image(as(nb2listw(ncCC89.nb, zero.policy=TRUE), "CsparseMatrix"))
> anb <- aggregate(ncCC89.nb, interaction(nc.sids$M.id, nc.sids$L.id))
> image(as(nb2listw(anb, style="B"), "CsparseMatrix"))
> # when the neighbour object is not empty
> bnb <- nb2blocknb(anb, as.character(interaction(nc.sids$M.id,
>    nc.sids$L.id)))
> image(as(nb2listw(bnb, style="B"), "CsparseMatrix"))
> # and when the neighbour object is empty
> anb1 <- lapply(anb, function(x) x <- 0L)
> attributes(anb1) <- attributes(anb)
> bnb1 <- nb2blocknb(anb1, as.character(interaction(nc.sids$M.id,
>    nc.sids$L.id)))
> image(as(nb2listw(bnb1, style="B"), "CsparseMatrix"))
>
> This isn't your case, but crafting an nb object by hand (adding
> attributes after creating the list) then using spdep::union.nb or similar
> to combine with a positional nb (such as poly2nb) may work. For parcels
> across a stream or street, maybe look at the snap= argument if the streets
> are narrower than frontages. Could you provide a small reproducible
> example?
>
> Hope this clarifies,
>
> Roger
>
> >
> > All ideas welcome,
> > Dexter
> >
> >       [[alternative HTML version deleted]]
> >
> > _______________________________________________
> > R-sig-Geo mailing list
> > [hidden email]
> > https://stat.ethz.ch/mailman/listinfo/r-sig-geo
> >
>
> --
> Roger Bivand
> Department of Economics, Norwegian School of Economics,
> Helleveien 30, N-5045 Bergen, Norway.
> voice: +47 55 95 93 55; e-mail: [hidden email]
> http://orcid.org/0000-0003-2392-6140
> https://scholar.google.no/citations?user=AWeghB0AAAAJ&hl=en
>

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo