How to Attach a Simple Data.Frame to a Spatialpolygondataframe in R

How to attach a simple data.frame to a SpatialPolygonDataFrame in R?

Let df = data frame, sp = spatial polygon object and by = name or column number of common column. You can then merge the data frame into the sp object using the following line of code

sp@data = data.frame(sp@data, df[match(sp@data[,by], df[,by]),])

Here is how the code works. The match function inside aligns the columns so that order is preserved. So when we merge it with sp@data, order is correctly preserved. A quick check to see if the code has worked is to inspect the two columns corresponding to the common column and see if they are identical (the common columns get duplicated and it is easy to remove the copy, but i keep it as it is a good check)

Joing dataframe and spatial polygon dataframe in R

The error message gives you a hint:

no applicable method for 'inner_join' applied to an object of class
"character"

Just join the two data frames instead of the character vector and factor:

mydf <- inner_join(vietnam@data,df,by="VARNAME_1")

Or, if you want to retain the spatial object,

mydf <- sp::merge(vietnam, df, by="VARNAME_1", all=F)

Adding a column frame a data frame to a spatial polygons data frame in R

EDIT

Taking into account @Robert's suggestion, it is better to omit the explicit call to @data.
You can add a column to your shp file by:

b$Province<-c("provinces", "names", "ecc")

or like this if you now that the order of Province in a correspond to the element of b

b$Province<-a$Province

then merge a to b with merge:

b <-merge(b,a,by="Province")

This should work. However, there are different way to do the same things.

EDIT
I add an example with some data. This example is not reproducible but should drive you in the right direction:

library(raster)
shp <- shapefile("dati/Limiti_2016_WGS84_Italia/regioni/basilicata_provincie.shp")
plot(shp)

Sample Image

data.frame(shp)

SHAPE_Leng SHAPE_Area X_sum
0 593511.8 6593536923 4751953
1 367848.1 3479205085 1371840

create a toy data.frame

df <- data.frame(provincie=c("A","B"),pop=c(10000,20000),covid=c(2000,3500))
shp$provincie <- df$provincie

now the shp looks like this

  SHAPE_Leng SHAPE_Area   X_sum provincie
0 593511.8 6593536923 4751953 A
1 367848.1 3479205085 1371840 B

finally, we can merge the two

shp <- merge(shp,df,by="province")
data.frame(shp)

the output is:

  provincie SHAPE_Leng SHAPE_Area   X_sum   pop covid
1 A 593511.8 6593536923 4751953 10000 2000
2 B 367848.1 3479205085 1371840 20000 3500

but the class of shp is preserved

> class(shp)
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"

Merge data frame with SpatialPolygonsDataFrame

Caveat: I've never done this before so I'm "feeling my way around". First look at the object-states:

Note: this was with rgdal_0.9-3 and sp_1.1-1 loaded under R 3.2.1 (and with GDAL installed on my OSX system, from kingchaos, IIRC):

> str(states)
Formal class 'SpatialPolygonsDataFrame' [package "sp"] with 5 slots
..@ data :'data.frame': 52 obs. of 9 variables:
.. ..$ STATEFP : Factor w/ 52 levels "01","02","04",..: 5 9 10 11 13 14 16 18 19 21 ...
.. ..$ STATENS : Factor w/ 52 levels "00068085","00294478",..: 22 17 2 18 27 28 29 30 16 19 ...
.. ..$ AFFGEOID: Factor w/ 52 levels "0400000US01",..: 5 9 10 11 13 14 16 18 19 21 ...
.. ..$ GEOID : Factor w/ 52 levels "01","02","04",..: 5 9 10 11 13 14 16 18 19 21 ...
.. ..$ STUSPS : Factor w/ 52 levels "AK","AL","AR",..: 5 8 10 11 14 15 13 18 19 21 ...
.. ..$ NAME : Factor w/ 52 levels "Alabama","Alaska",..: 5 9 10 11 13 14 16 18 19 21 ...
.. ..$ LSAD : Factor w/ 1 level "00": 1 1 1 1 1 1 1 1 1 1 ...
.. ..$ ALAND : num [1:52] 4.03e+11 1.58e+08 1.39e+11 1.49e+11 2.14e+11 ...
.. ..$ AWATER : num [1:52] 2.05e+10 1.86e+07 3.14e+10 4.95e+09 2.40e+09 ...
..@ polygons :List of 52
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 6
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] -118.4 33.4
.. .. .. .. .. .. ..@ area : num 0.0259
.. .. .. .. .. .. ..@ hole : logi FALSE
##### Snipped rest of output ............................

So after looking for help on merge and reading:

 ?merge   # and choosing the option for:

Merge a Spatial* object having attributes with a data.frame
(in package sp in library /Library/Frameworks/R.framework/Versions/3.2/Resources/library)

I decided to try (and appear to have succeeded:

> newobj <- merge(states, my_counts, by.x="STUSPS", by.y="State")
Warning message:
In .local(x, y, ...) : 8 records in y cannot be matched to x

> names(newobj@data)
[1] "STUSPS" "STATEFP" "STATENS" "AFFGEOID" "GEOID" "NAME"
[7] "LSAD" "ALAND" "AWATER" "count"

The warning makes sense. You seem to have some extra "States" not anticipated by the authors of that "states" shp-file:

> length( table(my_counts$State))
[1] 60
> length( unique(states@data$STUSPS) )
[1] 52

The moral

You should look at the names-values in the two objects when you are merging:

> names(states)
[1] "STATEFP" "STATENS" "AFFGEOID" "GEOID" "STUSPS" "NAME" "LSAD"
[8] "ALAND" "AWATER"

> names(my_counts)
[1] "State" "count"

How to convert data.frame to SpatialPolygonsDataFrame

You need to assign df to df %>% mutate_if(is.numeric, round), i.e.

df <- df %>% mutate_if(is.numeric, round)

Otherwise you df remained unchanged.

Also, nothing stops you from doing this:

Hex_Grid_Pop@data[,3:13] <- Hex_Grid_Pop@data[,3:13] %>% mutate_if(is.numeric, round)

Adding a Polygon to a SpatialPolygonsDataFrame

The following code creates a rectangle that encloses the original spatial polygons and adds this as a spatial polygon to the original shape.

library(rgdal)
library(rgeos)

dsn <- system.file("vectors", package = "rgdal")[1]
Scotland <- readOGR(dsn=dsn , layer="scot_BNG")

# change the width parameter to make the rectangle the desired size
# this results in an extent object that surrounds the original shape
eScotland <- extent(gBuffer(Scotland, width = 50000))
# turn the extent into a Spatial Polygon
pScotland <- as(eScotland, 'SpatialPolygons')
crs(pScotland) <- crs(Scotland)
newScotland <- bind(pScotland, Scotland)
plot(newScotland)

Sample Image

Create a spatial polygons data frame that preserves overlapping features with another spatial polygons data frame but does not clip polygon extent

If I understand the question properly, you could use function gIntersects to find out which watersheds intersect your region, and then extract only those from the huc4 dataset. In practice, something like this could work:

intersects <- which(gIntersects(huc4, region, byid = TRUE))
huc4_clip <- huc4[intersects, ]


Related Topics



Leave a reply



Submit