Hot answers tagged

50

I used as(nc, 'Spatial') as part 2 of the vignette by Edzer Pebesma indicated (Scroll to the bottom of the page).


50

To drop the geometry column, use st_drop_geometry(): library(sf) nc <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE) nc_df2 <- nc %>% st_drop_geometry() class(nc_df2) #> [1] "data.frame" Before st_drop_geometry() was added to the sf package (in November, 2018), one could produce the same result ...


49

Have you tried st_as_sf() which converts object (sp, dataframe, ...) to an sf object? library(data.table) library(sf) # your data (removed crs column) DT <- data.table( place=c("Finland", "Canada", "Tanzania", "Bolivia", "France"), longitude=c(27.472918, -90.476303, 34.679950, -65.691146, 4.533465), ...


47

Set the st_geometry property to NULL. library(sf) nc <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE) class(nc) ## [1] "sf" "data.frame" st_geometry(nc) <- NULL class(nc) ## [1] "data.frame" Also (though this won't remove the attr(nc, "sf_column"): nc <- st_read(system.file("shape/nc.shp", package="sf"), quiet = ...


29

Since today, there is a st_crop function in the github version of sf (devtools::install_github("r-spatial/sf"), probably on CRAN in the near future too). Just issue: st_crop(nc, c(xmin=-82, xmax=-80, ymin=35, ymax=36)) The vector must be named with xmin xmax ymin ymax (in whichever order). You can also use any object that can be read by st_bbox as ...


23

You can get the same result by using st_join: First create a demo polygon and some points with sf. library(sf) library(magrittr) poly <- st_as_sfc(c("POLYGON((0 0 , 0 1 , 1 1 , 1 0, 0 0))")) %>% st_sf(ID = "poly1") pts <- st_as_sfc(c("POINT(0.5 0.5)", "POINT(0.6 0.6)", "POINT(3 3)")) %>% st_sf(ID =...


21

You can cast an sf object to sp, for packages that don't yet support sf - I do this a fair bit for raster/polygon interactions. So you could do: simplepolys <- rmapshaper::ms_simplify(input = as(sfobj, 'Spatial')) %>% st_as_sf()


20

st_intersection is probably the best way. Find whatever way works best to get an sf object to intersect with your input. Here's a way using the convenience of raster::extent and a mix of old and new. nc is created by example(st_read): st_intersection(nc, st_set_crs(st_as_sf(as(raster::extent(-82, -80, 35, 36), "SpatialPolygons")), st_crs(nc))) I don't ...


15

Just use c like its a vector: > (sfc12 = c(sfc1, sfc2)) Geometry set for 2 features geometry type: POINT dimension: XY bbox: xmin: 0 ymin: 1 xmax: 1 ymax: 1 epsg (SRID): NA proj4string: NA POINT(0 1) POINT(1 1) And the length is 2: > length(sfc12) [1] 2


14

It's faster and easier to use st_intersects, no need to loop. The output is a bit obscure, essentially a classed list of feature IDs intersected, so we get the lengths() which is the number of points inside each feature. First polygon has six points in it, in this example. library(sf) #> Linking to GEOS 3.7.0, GDAL 2.4.0, PROJ 5.2.0 poly <- ...


13

You've not attached the dplyr package: > e %>% filter(ADMIN_NAME=="Durham") Error in data.matrix(data) : (list) object cannot be coerced to type 'double' When you do, you'll see that dplyr stomps on the base R filter function with its own filter function: > library(dplyr) Attaching package: ‘dplyr’ The following objects are masked from ‘...


12

You can do this using the append flag on sf::st_write(): library(sf) nc <- st_read(system.file("shape/nc.shp", package="sf")) storms <- st_read(system.file("shape/storms_xyz.shp", package="sf")) st_write(nc, "nc.gpkg", "nc") st_write(storms, "nc.gpkg", "storms", append = TRUE) st_layers("nc.gpkg") ## Driver: GPKG ## Available layers: ## ...


12

What you are looking can be done using sf::st_intersects() as commented. I provide a full working example using USA states. library(magrittr) library(ggplot2) library(sf) tt <- read_sf(path, "USA_adm1") # subset some states to make it plot faster tt1 <- tt[tt$NAME_1 %in% c("South Dakota", "Wyoming", "Nebraska", "Iowa"), ] ...


10

I had to use sf:::as_Spatial() as workaround. library(sf) nc <- st_read(system.file("shape/nc.shp", package="sf")) # sf -> sp nc_sp <- as_Spatial(nc$geom) # Error: could not find function "as_Spatial" nc_sp <- sf:::as_Spatial(nc$geom) # This works library(sp) plot(nc_sp)


10

Drawing from @TimSalabim's answer, if your sfc objects are in the same CRS you can use do.call(rbind, list(sfc1, sfc2)).


9

Here is an answer that applies sf package functions to the reproducible data kindly provided by rcs. library(sf) A <- st_as_sfc("LINESTRING(458.1 768.23, 455.3 413.29, 522.3 325.77, 664.8 282.01, 726.3 121.56)") B <- st_as_sfc("MULTIPOLYGON(((402.2 893.03, 664.8 800.65, 611.7 666.13, 368.7 623.99, 215.1 692.06, 402.2 893.03)), ((703.9 366.29, 821.2 ...


9

I think this should do what you want. Essentially what I mentioned in my comment. One thing I didn't mention is that you will want to transform to an appropriate equal-area projection that uses metres so that you can buffer by 100m and be confident that the areas calculated across your study are equivalent. I don't know the correct one for Switzerland, but ...


9

I think that the sf package need to know first how you want to create the lines from your points. I mean which pair of POINT make every LINESTRING. In my example that was defined inside the lapply function. Follow the reproducible and commented code below, hope that helps: # Load library library(sf) # Create points data multipoints <- st_multipoint(...


9

You could also do this using dplyr's group_by() and summarize() functions: states %>% group_by(group_var) %>% summarize(geometry = st_union(geometry))


8

I figured it out. The polygons need to be manually closed by rbinding the first row: state_data <- ggplot2::map_data("state") state_data_sf <- lapply(unique(state_data$region), function(x) list(matrix(unlist( rbind( state_data[state_data$region == x,][,c("long", "lat")], ...


8

st_cast is what you are looking for. library(sf) library(mapview) ls <- st_sfc(st_linestring(rbind(c(0,0),c(0,1))), st_linestring(rbind(c(0,0),c(10,0)))) ptns = st_cast(ls, "POINT") mapview(ls, color = "red") + ptns You can also cast to MULTIPOINT if you wish. Edit: As mentioned by @Spacedman in the comments, this returns 4 points, ...


8

Loop over each geometry with mapply? For any two geometry column vectors: > set.seed(1) > g1 = st_geometry(nc); g2= st_geometry(dplyr::sample_frac(nc)) > mapply(st_distance, g1, g2) [1] 152687.52 390721.95 105485.92 363253.27 214961.38 66748.80 309538.72 [8] 11825.65 213627.60 273758.95 198366.26 0.00 66634.13 331566.88 [15] 251378....


8

The answer provided is related to this question How to subset a SpatialPoints object to get the points located on each side of a SpatialLines object using R? but using sf library instead of sp. Check the commented code below. # Load Libraries ---------------------------------------------------------- library('sf') # Test data ----------------------------...


8

I get much faster results with velox if I crop the raster before running extract, e.g.: r <- velox("testras_so.tif") r$crop(poly) r$extract(poly) I've also been working on a package with an optimized extract function that may be of interest: library(exactextractr) exact_extract(ras, poly) # get a matrix with weights and values, ...


8

When you read a CSV with no options the driver doesn't know where the coordinate columns are so returns a data frame: library(sf) > st_read("./pts.csv") Reading layer `pts' from data source `/home/rowlings/Downloads/SO/csv/pts.csv' using driver `CSV' id x y 1 1 10.1 2.1 2 2 2.4 12.1 3 3 3.2 4.5 Warning message: no simple feature ...


8

STOP USING SO MANY PIPES!!! n_grid <- (area_box / (area_box - area_shp ) )*n_points %>% sqrt() is doing n_grid <- (area_box/(area_box - area_shp)) * (n_points %>% sqrt()) in other words its square-rooting n_points. Fix that and I get exactly 200 points. The pipe operator has high priority: > 3 * 9 %>% sqrt() [1] 9 > 3 * (9 %>...


7

While sf package don't have a built-in function or geosphere is not compatible with sf objects I would use a wrapper around geosphere::dist2Line function: just getting the matrix of coordinates instead using the entire sf object. I also tried @jsta answer based on sampling the line and I compared the differences between both approaches. Since I'm working ...


7

The solution was to union the geometries first, like so: diffPoly <- st_difference(polys.df_sf, st_union(polys.df_sf2))


7

You can do the intersection of polygons and then filter those that overlap. inter <- st_intersection(poly) %>% filter(n.overlaps < 2) plot(inter %>% select(var)


7

If you snap the point to the line then you can split the line and then extract the parts from the resulting collection. Use a really small tolerance, I don't know how small it needs to be... > site_snap = st_snap(site, reach, tol=1e-9) > parts = st_collection_extract(st_split(reach$geometry, site_snap$geometry),"LINESTRING") parts is now two features,...


Only top voted, non community-wiki answers of a minimum length are eligible