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)
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)
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
Data.Table Alternative for Dplyr Case_When
Calling a Function from a Namespace
Apply() Is Slow - How to Make It Faster or What Are My Alternatives
How to Set Unique Row and Column Names of a Matrix When Its Dimension Is Unknown
Merge/Combine Columns with Same Name But Incomplete Data
Keep Document Id with R Corpus
Changing the Outlier Rule in a Boxplot
Plot Mean and Sd of Dataset Per X Value Using Ggplot2
How to Adjust Facet Size Manually
Determining the Distance Between Two Zip Codes (Alternatives to Mapdist)
How to Refer to a Variable Name with Spaces
Update Graph/Plot with Fixed Interval of Time
Shiny Selectinput to Select All from Dropdown