I always get error to this
# polygon that to be window
neighborhoods <- st_read("neighborhoods/neighborhoods.shp")
# convert CRS to planar projection as recommended by (https://stackoverflow.com/questions/59597078/use-sf-polygon-object-as-window-in-spatstat)
neighborhoods_3857 <- st_transform(neighborhoods, crs = 3857)
# point that to be PPP spatstat
trees <- st_read("trees/trees.shp")
# convert to planar projection
trees_3857 <- st_transform(trees, crs = 3857)
The problems, the "trees_3857" doesn't have dataframe columns that represent in EPSG3857 coordinates, so Feature column of "trees_3857" doesn't have x and y columns that respect to EPSG 3857
q <- ppp(x=?, y=?, win=neighborhoods_3857)
what I have done but error
z <- as.ppp(trees_3857, win=neighborhoods_3857)
Error in as.ppp.sf(trees_3857, win = neighborhoods_3857): unused argument (win = neighborhoods_3857)
Traceback:
You can get the data freely from datacamp.
https://assets.datacamp.com/production/repositories/738/datasets/96a72364e69d872645038b3a6dc7c0dbcb1114d6/neighborhoods.zip
https://assets.datacamp.com/production/repositories/738/datasets/08a3684dc4d538d59ba051a64a834166883ab5d1/trees.zip
Although you're wanting to transform your data into an object of class "ppp" from the spatstat package, the error message indicates that the problem originated in the function as.ppp.sf which is part of the sf package.
The error message says unused argument: win which means that the function did not recognise or accept the argument win.
Just to make it more challenging, the function as.ppp.sf is not documented and is not visible... By typing sf:::as.ppp.sf we can see the function body and figure out that the function has only one argument, so it does not accept any window information.
This is not the way the generic function as.ppp is designed to work in the spatstat package, so if you looked for help(as.ppp) in spatstat, it's not surprising that you got confused.
The best solution is (as Ege Rubak suggests) to convert the point coordinates and then add the window information:
z <- as.ppp(trees_3857)
Window(z) <- as.owin(neighborhoods_3857)
The conversions as.ppp and as.owin will be executed using code in sf so I can't guarantee they will work. The assignment Window(z) <- will be executed in spatstat code, see help("Window<-.ppp").
Related
I have a SpatialPointsDataFrame called johnny, created from a vanilla dataframe by assigning coordinates. These coordinates are in coordinate system EPSG 4326 (the standard GPS geographic coordinate system), but johnny does not know that. So ,I am trying to assign EPSG 4326 to johnny, essentially as in this earlier question data projection in R using package SP . I, too, am using sp. My ultimate goal is to project johnny to projected_johnny. However, I can't seem to assign the existing projection correctly first. Who sees my mistake?
library(sp)
x <- seq(80,90,by=1)
y <- seq(40,50,by=1)
value <- seq(10,20,by=1)
johnny <- data.frame(cbind(x,y,value))
coordinates(johnny) <- ~x+y
class(johnny)
[1] "SpatialPointsDataFrame"
attr(,"package")
[1] "sp"
proj4string(johnny) <- CRS("+init=epsg:4326")
Error in if (is.na(get("has_proj_def.dat", envir = .RGDAL_CACHE))) { :
argument is of length zero
I have considered and rejected the following possible solutions after trying them out:
Adding library rdgal directly
using CRS("+proj=longlat +datum=WGS84") instead of CRS("+init=epsg:4326")
I am using R 3.6.0 and sp 1.3-1. The rgdal version loaded via sp is 1.5-15. Any ideas are welcome. This should be such a simple action...
I looked over your code and guessed what you are probably trying to accomplish. But the way you are going about things is more different than it needs to be. There is a simple way to accomplished this. By far, the easiest way to accomplish this is by using those tools found in the R, sf package. Know that the sf package is a newer package than the sp package. And the sf package provides easy to use tools for accomplishing these tasks.
The code below is somewhat different from your code. A two column matrix was used instead of your three column data frame.
The simple feature geometry points were created from the matrix. Then the simple feature column object was created from the geometry points. Then the plot was created.
Code:
# Create matrix
x <- seq(80,90,by=1)
y <- seq(40,50,by=1)
# value <- seq(10,20,by=1)
#johnny <- data.frame(cbind(x,y))
jm <- matrix(data = c(x,y), nrow = 11, ncol = 2)
# coordinates(johnny) <- ~x+y
# class(johnny)
# johnny
Create sf multipoint geometry:
jm.sfg <- st_multipoint(jm)
jm.sfg
Create sf column object:
jm.sfc <- st_sfc(jm.sfg, crs = 4326)
jm.sfc
Plot
plot(jm.sfc, axes = TRUE)
The plot can be viewed from link below.
I am trying to get the intersection of two shapefiles (census tracts that fall within the boundaries of certain metropolitan areas). I am able to successfully get the intersecting features, however when I try to convert the output of sf_intersect to a SpatialPolygonsDataframe I get the error:
"Error in as_Spatial(from) : conversion from feature type
sfc_GEOMETRY to sp is not supported"
This is my code:
library(sf)
library(dplyr)
library(tigris)
library(sp)
#download shapefiles corresponding to metro areas
metro_shapefiles<-core_based_statistical_areas(cb = FALSE, year = 2016)
#convert to sf and filter
metro_shapefiles<-st_as_sf(metro_shapefiles)%>%filter(GEOID==31080 )
#Data for California
census_tracts_california<-tracts(state="CA",year=2016)
census_tracts_california<-st_as_sf(census_tracts_california)
#INTERSECT AND CONVERT BACK TO SP
census_tracts_intersected1<-st_intersection(census_tracts_california,
metro_shapefiles)
#back to spatial
census_tracts_intersected1<-as(census_tracts_intersected1,"Spatial")
The error message is telling you you can't convert an sfc_GEOMETRY to a Spatial object. There is no sp equivalent object.
In your intersection result you have a mixture of geometries (and hence, you're returned an sfc_GEOMETRY as your 'geometry'). You can see all the geometries here:
types <- vapply(sf::st_geometry(census_tracts_intersected1), function(x) {
class(x)[2]
}, "")
unique(types)
# [1] "POLYGON" "MULTILINESTRING" "MULTIPOLYGON"
If you want, you can extract each type of geometry, and convert those to SP individually:
lines <- census_tracts_intersected1[ grepl("*LINE", types), ]
polys <- census_tracts_intersected1[ grepl("*POLYGON", types), ]
spLines <- as(lines, "Spatial")
spPolys <- as(polys, "Spatial")
Additional Information
I mentioned in the comments you could use st_join. However, this may not give you the result you want. Within sf library there are the geometric binary predicates, such as ?st_intersects, and geometric operations such as ?st_intersection
The predicates return a sparse (default) or dense matrix telling you with which geometry of y each geometry of x intersects. If you use this within st_join, it will return the (original) geometries that intersect, rather than the sparse matrix.
Whereas the operations (e.g. st_intersection) will compute the intersection, and return new geometries.
Example use
The predicates (st_intersects) can be used inside st_join, and they will return the original geometries which 'intersect'
sf_join <- sf::st_join(census_tracts_california, metro_shapefiles, join = st_intersects)
In this case this gives a single type of object
types <- vapply(sf::st_geometry(sf_join), function(x) {
class(x)[2]
}, "")
unique(types)
# [1] "MULTIPOLYGON"
## so you can convert to a Spatial object
spPoly <- as(sf_join, "Spatial")
But you need to decide if the result of st_intersect is what you're after, or whether you need the new geometries given by st_intersection.
Further reading
information on each join is on the sf blog.
spatial predicates and examples of what the different operations do are on wikipedia (with some good illustrations)
Credit to user #lbussett for their description on the difference between st_intersect and st_intersection
Conversion to a Spatial object can't handle mixed lines and polygons. After the intersection you can extract just the polygons (and discard any lines) using:
st_collection_extract("POLYGON")
Your example doesn't seem to fail anymore, so I've created a new example that intersects two polygons, with a shared side. This results in an intersection output of a polygon and a line.
On the second attempt I've piped the intersection through the st_collection_extract() function prior to successful conversion to a Spatial object.
library(sf)
library(dplyr)
library(sp)
#Create some boxes
BoxA <- st_polygon(list(cbind(c(0,0,2,2,0),c(0,2,2,0,0))))
BoxB <- st_polygon(list(cbind(c(1,1,3,3,1),c(1,3,3,1,1))))
BoxC <- st_polygon(list(cbind(c(2,2,4,4,2),c(0,2,2,0,0))))
#Create a funny shaped union to help demonstrate the intersection issue
BoxAB <- st_union(BoxA,BoxB)
plot(BoxAB)
plot(BoxC,add=TRUE,border="blue")
Example polygons to intersect
#Intersect of BoxAB with BoxC results in a line and a polygon
BoxIntersects<-st_intersection(BoxAB,BoxC)
plot(BoxIntersects)
Intersection made up of a polygon and a line
#back to spatial fails
SpatialVersionOfIntersects<-as(BoxIntersects,"Spatial")
Error in .as_Spatial(from, cast, IDs) :
conversion from feature type sfc_GEOMETRY to sp is not supported
#Intersect again, but this time extract only the polygons
BoxIntersects<-st_intersection(BoxAB,BoxC) %>% st_collection_extract("POLYGON")
#back to spatial suceeds!
SpatialVersionOfIntersects<-as(BoxIntersects,"Spatial")
I am trying to convert a raster object to an .im object for use with a point process model in the spatstat package in R. I begin by creating the raster from a tiff file using the raster() package. No problems there. I then proceed by cropping the raster according to a given extent. Again, no problem there. I then specify a spatial window (owin) defined using the same extent. Still no problems. When I then proceed to the final step of converting the raster to the im object using as.im(), the function runs and the new im object is created, but it has somehow lost the pixel information that was contained in the original raster such that each pixel now has the same value in the im object. Any help or suggestions would be most appreciated. Thanks very much.
The date file used is at this link: https://www.dropbox.com/s/n67djm3n0tfa6sx/MGVF_2001_30_arc_sec.tif?dl=0
And the R code is as follows:
library(raster)
library(spatstat)
# First set the geographic extent we'll be using
e <- extent(-20, 60, -40, 35)
# Then read in the Maximum Green Vegetation Fraction tiff and crop it
mgvf <- raster("MGVF_2001_30_arc_sec.tif")
mgvf.2001.africa <- crop(mgvf, e)
# Now let's create a window for in spatstat
SP.win <- as(e, "SpatialPolygons")
W <- as(SP.win, "owin")
# Finally, we create the .im object
mgvf.img <- as.im(X = "mgvf.2001.africa", W = W)
# Notice, there are no errors thrown. However, compare the plots below and see the loss of information:
plot(mgvf.2001.africa)
plot(mgvf.img)
Incidentally, I have tried the above as shown as well as trying to replace the NAs in the raster prior to converting to im. The result is the same. Thanks.
I'm working with satellite tracked animals and have a load of relocation data.
So I have my map data and relocations as SpatialPointsDataFrames and when I ask
if proj4string(map)==proj4string(locs) I get TRUE.
But when I try the count.points function as follows
cp <- count.points(locs, map)
I get the following error
Error in count.points(SpatialPoints(x), w) :
different proj4string in w and xy
Does anyone have any ideas on why this is the case?
Edit Code:
load("mydata")
map = mydata$map
map
mimage(map)
locs= mydata$relocs
locs
image(map)
points(locs, col=as.numeric(slot(locs, "data")[,1]), pch=16)
cp <- count.points(locs, map)
Reproducible example would go a long, long way here. But generally speaking R's comparison of projection strings is approximately verbatim. So if there's an extra space or so forth, it will fail.
Given the out for proj4string(map), proj4string(locs), proj4string(SpatialPoints(locs)) in the comment, particularly that proj4string(SpatialPoints(locs)) is NA, I'd say that count.points is dropping the proj4string when it changes to a SpatialPoints object. I think the way to coerce a SPDF to SP while keeping the projection string is via as(x,"SpatialPoints").... Try using trace to insert that into count.points?
I am working with shapefiles in R, one is point.shp the other is a polygon.shp.
Now, I would like to intersect the points with the polygon, meaning that all the values from the polygon should be attached to the table of the point.shp.
I tried overlay() and spRbind in package sp, but nothing did what I expected them to do.
Could anyone give me a hint?
With the new sf package this is now fast and easy:
library(sf)
out <- st_intersection(points, poly)
Additional options
If you do not want all fields from the polygon added to the point feature, just call dplyr::select() on the polygon feature before:
library(magrittr)
library(dplyr)
library(sf)
poly %>%
select(column-name1, column-name2, etc.) -> poly
out <- st_intersection(points, poly)
If you encounter issues, make sure that your polygon is valid:
st_is_valid(poly)
If you see some FALSE outputs here, try to make it valid:
poly <- st_make_valid(poly)
Note that these 'valid' functions depend on a sf installation compiled with liblwgeom.
If you do overlay(pts, polys) where pts is a SpatialPointsDataFrame object and polys is a SpatialPolygonsDataFrame object then you get back a vector the same length as the points giving the row of the polygons data frame. So all you then need to do to combine the polygon data onto the points data frame is:
o = overlay(pts, polys)
pts#data = cbind(pts#data, polys[o,])
HOWEVER! If any of your points fall outside all your polygons, then overlay returns an NA, which will cause polys[o,] to fail, so either make sure all your points are inside polygons or you'll have to think of another way to assign values for points outside the polygon...
You do this in one line with point.in.poly fom spatialEco package.
library(spatialEco)
new_shape <- point.in.poly(pts, polys)
from the documentation: point.in.poly "intersects point and polygon feature classes and adds polygon attributes to points".