I am using R.

I have a shapefile that gives me the provincial boundaries for a state and I want to use another dataset to combine the aggregate total enrolment in schools by 'district' to the shapefile. Since it is one-to-one merge, I thought a simple cbind should work but the file that is created is a list and I cannot map the density of enrolment onto the shapefile using the tmap function.

combined<- cbind(punjab, emis_data, by="ADM2_EN")

The other alternative is to use the merge command with aggregate function but that gives me all NAs in the total enrolment column.

Why might this be happening?

  • 1
    Welcome to GIS.se! Could you click 'edit' and add some more information about the data you are working with (structure of the attribute fields), and the R libraries you are using?
    – Simbamangu
    Nov 23, 2020 at 5:47
  • Using cbind is not correct, look at ?merge or ?dplyr::left_join. Since you do not provide a code example we cannot say anything regarding "Why might this be happening?". Have you looked at the arguments for merge? There are several that control how the merge returns results (eg., all.x, all, all.y). Apr 26, 2021 at 18:28

1 Answer 1


You can merge attribute tables / dataframes using merge and a shared id/name.

Load a spatial dataset using sf:

parks <- read_sf("~/workspace/_temp/ZM_parks.shp")

Resulting data:

Simple feature collection with 4 features and 1 field
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 22.29239 ymin: -16.69977 xmax: 30.3777 ymax: -12.3986
CRS:            4326
# A tibble: 4 x 2
  name                                                            geometry
  <chr>                                                      <POLYGON [°]>
1 Kasanka    ((30.08454 -12.4032, 30.08514 -12.40292, 30.08713 -12.40218,…
2 Kafue      ((26.54187 -14.48086, 26.54334 -14.48032, 26.5448 -14.47933,…
3 Liuwa Pla… ((22.37276 -14.21263, 22.37328 -14.21284, 22.37382 -14.21283…
4 Lusaka     ((28.34302 -15.49064, 28.43507 -15.49114, 28.43567 -15.49218…

Create a matching set of data on name:

prefs <- data.frame(name = c("Kasanka", "Kafue", "Liuwa Plains", "Lusaka"),
                    preference = c(4, 1, 3, 2))


merge(parks, prefs, by = "name")

Result is the spatial object with a new column for 'preferences':

Simple feature collection with 3 features and 2 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 25.21394 ymin: -16.69977 xmax: 30.3777 ymax: -12.3986
CRS:            4326
     name preference                       geometry
1   Kafue          1 POLYGON ((26.54187 -14.4808...
2 Kasanka          4 POLYGON ((30.08454 -12.4032...
3  Lusaka          2 POLYGON ((28.34302 -15.4906...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.