Joignez des données de points spatiaux avec plusieurs données de polygones à l'aide de R

8

Je veux joindre spatialement avec SpatialPolygonsDataFrame et SpatialPointsDataFrame.

obtenir une seule donnée ponctuelle dans plusieurs polygones, sous le code.

sp::over(meuse, srdf)

Certains points de données dans plusieurs polygones. Je veux que les données de points conservent toutes les données de polygone.

par exemple: point A dans les polygones a et b.

peut maintenant obtenir:

| point | polygon |
-------------------
| A     | a       |

Je reçois comme ça:

| point | polygon |
-------------------
| A     | a       |
| A     | b       |

Utiliser des données:

    coordinates(meuse) = ~x+y
    sr1=Polygons(list(Polygon(cbind(c(180114, 180553, 181127, 181477, 181294, 181007, 180409,
                                      180162, 180114), c(332349, 332057, 332342, 333250, 333558, 333676,
                                                         332618, 332413, 332349)))),'1')
    sr2=Polygons(list(Polygon(cbind(c(180042, 180545, 180553, 180314, 179955, 179142, 179437,
                                      179524, 179979, 180042), c(332373, 332026, 331426, 330889, 330683,
                                                                 331133, 331623, 332152, 332357, 332373)))),'2')
    sr3=Polygons(list(Polygon(cbind(c(179110, 179907, 180433, 180712, 180752, 180329, 179875,
                                      179668, 179572, 179269, 178879, 178600, 178544, 179046, 179110),
                                    c(331086, 330620, 330494, 330265, 330075, 330233, 330336, 330004,
                                      329783, 329665, 329720, 329933, 330478, 331062, 331086)))),'3')
    sr4=Polygons(list(Polygon(cbind(c(180304, 180403,179632,179420,180304),
                                    c(332791, 333204, 333635, 333058, 332791)))),'4')
    sr5=Polygons(list(Polygon(cbind(c(179500, 180000, 180000, 179500),
                                    c(331000, 331000, 331500, 331500)))), '5')
    sr=SpatialPolygons(list(sr1,sr2,sr3,sr4, sr5))
    srdf=SpatialPolygonsDataFrame(sr, data.frame(row.names=c('1','2','3','4', '5'), PIDS=1:5, y=runif(5)))
ogw
la source

Réponses:

5

La st_joinfonction du sfpackage ( version de développement ) fournit une solution simple et intuitive. Il renvoie la jointure spatiale en tant que data.frame, et vous pouvez facilement la reconvertir en Spatial*.

# Convert to sf-objects
srdf.sf <- st_as_sf(srdf)
meuse.sf <- st_as_sf(meuse)

# Keep all "meuse.sf", sort by row.names(meuse.sf). Default overlay is "intersects".
meuse_srdf <- st_join(meuse.sf, srdf.sf) 

# Keeps all "srdf.sf", sort by row.names(srdf.sf)
srdf_meuse <- st_join(srdf.sf, meuse.sf)

# Convert back to Spatial*
meuse_srdf <- as(meuse_srdf, "Spatial")
srdf_meuse <- as(srdf_meuse, "Spatial")

ÉDITER:

st_joinest maintenant dans la version CRAN de sf, comme indiqué précédemment par SymbolixAU.

eivindhammers
la source
1
st_joinest maintenant dans la version CRAN publiée
SymbolixAU
4

Utilisation over(meuse, srdf, returnList=TRUE)

 if ‘returnList’ is TRUE, a list of length
 ‘length(x), with list element ‘i’ the vector of all indices of
 the geometries in ‘y’ that correspond to the $i$-th geometry in
 ‘x’.

Le premier point recouvre un polygone, le 135e point en recouvre deux:

> rr = over(meuse,srdf,returnList=TRUE)
> rr[[1]]
  PIDS         y
1    1 0.2069365
> rr[[135]]
  PIDS          y
2    2 0.34809708
5    5 0.08942346

Notez que si vous ne voulez que les index de polygones superposés et pas tous les attributs, convertissez simplement les polygones en SpatialPolygons et vous obtenez une liste de numéros d'index plutôt que des blocs de données avec tous les attributs dans:

> rr = over(meuse,as(srdf,"SpatialPolygons"),returnList=TRUE)
> rr[[1]]
[1] 1
> rr[[135]]
[1] 2 5
Spacedman
la source
0

Je peux obtenir data.frame sous le code:

library(tidyverse)
sp::over(meuse, srdf, returnList=TRUE) %>%
plyr::ldply(., data.frame) -> tmp

C'est la .idcolonne ajoutée automatiquement .
Si vous obtenez des données de meuse filtrées ou modifiées, faites-le sous le code.

use_id <- 
  tmp %>% select(`.id`) %>% unlist(., use.names = F)
rownames(meuse) %in% use_id
ogw
la source