Ritaglia oggetto semplice funzionalità in R


20

Esiste una funzione per ritagliare l'oggetto mappa sf, simile a quella maptools::pruneMap(lines, xlim= c(4, 10), ylim= c(10, 15))usata per SpatialPolygon o SpatialLine?

Sto considerando st_intersection()ma può esserci un modo corretto.

Risposte:


17

st_intersectionè probabilmente il modo migliore. Trova il modo migliore per far sfintersecare un oggetto con il tuo input. Ecco un modo per usare la convenienza raster::extente un mix di vecchio e nuovo. ncè creato da example(st_read):

st_intersection(nc, st_set_crs(st_as_sf(as(raster::extent(-82, -80, 35, 36), "SpatialPolygons")), st_crs(nc)))

Non penso che tu possa convincerti st_intersectiona non aver bisogno di un CRS di corrispondenza esatta, quindi imposta entrambi su NA o assicurati che siano uguali. Non ci sono strumenti facili per bbox / extension afaik, quindi usare raster è un buon modo per rendere le cose facili.


Grazie mille @mdsumner, ha funzionato come un fascino. Ho trascorso ore st_intersectionma non sono riuscito a risolverlo da solo.
Kazuhito,

Ora puoi usare spex::spexper sostituire la st_as_sf(as(...))chiamata. Inoltre, tmaptools::crop_shape()puoi farlo.
AF7

1
sfora include st_crop, vedere la mia risposta per i dettagli.
AF7,

23

Da oggi esiste una st_cropfunzione nella versione github di sf( devtools::install_github("r-spatial/sf"), probabilmente anche su CRAN nel prossimo futuro).

Emetti solo:

st_crop(nc, c(xmin=-82, xmax=-80, ymin=35, ymax=36))

Il vettore deve essere nominato con xmin xmax ymin ymax(in qualunque ordine).

Puoi anche usare qualsiasi oggetto che può essere letto st_bboxcome limite di ritaglio, il che è molto utile.


5

Un'altra soluzione alternativa, per me è stato più veloce per gli shapefile più grandi:

library(sf)
library(raster)
library(rgeos)
library(ggplot2)

# Load National Forest shapefile
# https://data.fs.usda.gov/geodata/edw/edw_resources/shp/S_USA.AdministrativeForest.zip
nf.poly <- st_read("S_USA.AdministrativeForest"), "S_USA.AdministrativeForest")

crop_custom <- function(poly.sf) {
  poly.sp <- as(poly.sf, "Spatial")
  poly.sp.crop <- crop(poly.sp, extent(c(-82, -80, 35, 36)))
  st_as_sf(poly.sp.crop)
}

cropped <- crop_custom(nf.poly)

Grazie. È un flusso di lavoro interessante, una combinazione di raster :: crop () e st_as_sf () ... + 1 da parte mia. Vorrei che potessimo avere questo tipo di funzione facilmente accessibile come crop () nelle versioni future di sf . Per quanto riguarda la velocità, una breve corsa di system.time con la tua funzione ha riportato l' utente: 5.42, sistema: 0.09, trascorso 5.52 , mentre l' st_intersection()approccio era utente: 1.18, sistema: 0.05, trascorso 1.23 sul tuo set di dati. (Probabilmente il mio ambiente è diverso dal tuo ... non sono sicuro.)
Kazuhito

È interessante: l'approccio st_intersection richiede circa 80 anni per me.
pbaylis,

Tieni presente che la funzione raster :: crop, quando applicata a oggetti geometria sp, agisce come un wrapper per le funzioni rgeos. Anche se un involucro molto conveniente. L'API GEOS funziona su oggetti WKT, quindi sarà invariabilmente uno standard per le operazioni di overlay sf.
Jeffrey Evans,

1
E cambia nel tempo, sf ora ha "indicizzazione spaziale" incorporato in 0,5-1 cran.r-project.org/web/packages/sf/news.html, quindi probabilmente è ora più veloce di sp / rgeos.
mdsumner,

1
sfora include st_crop, vedere la mia risposta per i dettagli.
AF7,

1

La soluzione di @ mdsumner in funzione. Funziona se rastaè un RasterBrick, un ext, un bbox, ecc.

# Crop a Simple Features Data Frame to the extent of a raster
crop.sf = function(sfdf, rasta) {
  st_intersection(sfdf, st_set_crs(st_as_sf(as(extent(rasta), "SpatialPolygons")), st_crs(sfdf)))
}

Elimina le informazioni crs del raster perché non so come convertire un crs raster () in uno st_crs ()

Sulla mia macchina e per il mio campione di dati questo ha prestazioni equivalenti a quelle raster::cropcon una versione SpatialLinesDataFrame dei dati.

La soluzione di @ pbaylis è circa 2,5 volte più lenta:

# Slower option.
crop.sf2 = function(sfdf, rasta) {
  st_as_sf(crop(as(sfdf, "Spatial"), rasta))
}

Modifica: il commento di Somebodies suggerisce spex , che produce SpatialPolygons con i crs della rasta, se ha un crs.

Questo codice utilizza lo stesso metodo di spex:

# Crop a Simple Features Data Frame to the extent of a raster
crop.sf3 <- function(sfdf, rasta) {
  # Get extent and crs
  ext.sp <- as(extent(rasta), "SpatialPolygons")
  crs(ext.sp) <- crs(rasta)

  # crop
  st_intersection(sfdf, st_as_sf(ext.sp))
}

sf ora ha una st_cropfunzione che probabilmente vale la pena provare.
cmc
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.