I want to create a map of China that demonstrates the value of the ethnic heterogeneity index. I want to generate the map as in this webpage, https://mgimond.github.io/Spatial/mapping-data-in-r.html

I gathered the .shp file of provinces from Hijmans, Robert J., University of California, Berkeley. Museum of Vertebrate Zoology. Second-level Administrative Divisions, China, 2015 [map]. No Scale Provided. Retrieved April 15, 2021, from https://geodata.lib.utexas.edu/catalog/stanford-nt024fn0432

But I do not know how to append "ethnic heterogeneity index" to this file? The ethnic heterogeneity index is stored as a CSV. file and the common variable for both files is "province". My current csv file does not contain the longitude and latitude information for provinces, is that the problem?

chinaprovincedf <- as(chinaprovince, "data.frame")
Error in as(chinaprovince, "data.frame") : 
  internal problem in as(): “sf” is(object, "data.frame") is TRUE, but the metadata asserts that the 'is' relation is FALSE

I am not sure how to proceed.

  • If you have read your shapefile with sf you just need to merge with merge(shapefile, mycsv) as usual, assuming that they share a common variable. The result is a sf with the data from mycsv
    – dieghernan
    Apr 15, 2021 at 16:45
  • Here is a beginner-friendly tutorial on the joining process that we developed recently : andysouth.shinyapps.io/join-admin e.g. it deals with frequent issues when the names of regions in the shapefile don't match exactly those in the csv. Good luck. Feedback welcome.
    – Andy
    Apr 15, 2021 at 16:50

1 Answer 1


# this are the polygons
china = read_sf("https://geodata.lib.utexas.edu/download/file/stanford-nt024fn0432-geojson.json")

# make a dummy data.frame for the example
# in your case use read.csv for your file
# check we change the name here to illustrate the join
china_heterogeneity = data.frame(province = china$name_2, heterogeneity = runif(seq_along(china$name_2)) )

# you may see there's no geometry in this data frame
  province heterogeneity
1   Anqing     0.2678299
2   Bengbu     0.6505222
3   Bozhou     0.3048307
4   Chaohu     0.9352014
5  Chizhou     0.5902616
6  Chuzhou     0.0210071

# we use left join, in the "by" argument we pass the common variable, as named in # both data frames
left_join(china, china_heterogeneity, by = c("name_2" = "province")) %>%
  select(heterogeneity) %>% plot(graticule = T)

enter image description here

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.