Fuzzy Match
Joining of the CO2 and country_list datasets based on the country name attribute in both datasets.
As the country names may not 100% match, a fuzzy match of the country names and manual mapping of any unmatched names is completed to allow for the two datasets to be used together.
# Set country names to lower in both files to avoid case sensitivity
co2$country_name <- tolower(co2$Entity)
country_list$country_name <- tolower(country_list$`COUNTRY NAME`)
# Function to fuzzy match country names
unmatched_country_names <- function(df1, df2, column_name){
df1_col <- unique(select(df1,column_name))
df2_col <- unique(select(df2,column_name))
name_matches <- stringdist_left_join(x = df1_col, y= df2_col, max_dist=0)
# Return all positive matches from fuzzy join which are NOT exact matches
positive_name_matches <- name_matches %>% filter(complete.cases(.))
filter(positive_name_matches, !(1 == 2))
unmatched <- name_matches %>% filter_all(any_vars(is.na(.)))
return(unmatched)
}
# Return a dataframe of country names which do not match between country_list and co2 datasets
unmatched <- unmatched_country_names(co2,country_list, 'country_name')
Joining by: "country_name"
unmatched
43 rows with unmatched names.
Majority of the unmatched countries are either regions of the world (e.g. south america), countries with island, south, north or saint in their name or other records (e.g. world, annex b), which may have been abbreviated in the country_list dataset (e.g. north might be nth) or are irrelvant for our purposes.
Also several ‘annex b’ types, which are unknown.
All of these non-country records are to be removed.
# Non-countries in unmatched
non_countries <- c('africa', 'asia', 'central america', 'eu28', 'europe', 'kp annex b', 'middle east', 'non kp annex b', 'non-oecd', 'north america', 'oecd','oceania', 'statistical differences', 'world')
# Create a subset of the data excluding the non-country records
co2 <- subset(co2, !(country_name %in% non_countries))
# Group by country name and review for further non-country records
co2 %>%
group_by(country_name) %>%
summarise()
unmatched2 <- unmatched_country_names(co2,country_list, 'country_name')
Joining by: "country_name"
unmatched2
After re-running the match on the cleaned data, there are now 29 countries which do not have matched.
Options to match them could include regex or more detailed, prescriptive fuzzy matching, however given there are only 29 unmatched countries, resolved to manual match them.
# List of unmatched countries which have a corresponding record in the country_list dataset
unmatched_countries = c('czechoslovakia', 'democratic republic of congo', 'faeroe islands', 'falkland islands', 'gambia', 'micronesia (country)', 'north korea', 'palau', 'reunion', 'saint helena', 'saint kitts and nevis', 'saint lucia', 'saint pierre and miquelon', 'saint vincent and the grenadines', 'sint maarten (dutch part)', 'south korea', 'south sudan', 'yugoslavia')
# A list manually mapping the unmatched countries to the country_list dataset
manually_matched <- c('czech republic', 'congo', 'faroe islands', 'falkland islands (islas malvinas)', 'gambia the', 'micronesia, federated states of', 'korea, north', 'palau - trust territory of the pacific islands', 'reunion and associated islands', 'st. helena', 'st. kitts and nevis', 'st. lucia', 'st. pierre and miquelon','st. lucia and st. vincent', 'st. marteen, st. eustatius, and saba', 'korea, south', 'sudan', 'yugoslavia (& former territory)')
# Map and update the country names in co2 dataset using the manually_matched names
count <- 1
for (country in unmatched_countries) {
co2 <- co2 %>%
mutate(country_name = ifelse (country_name == country, country_name <- manually_matched[count], co2$country_name))
count <- count + 1
}
# Review the remaining unmatched countries
unmatched_round2 <- unmatched_country_names(co2,country_list, 'country_name')
Joining by: "country_name"
unmatched_round2
Manually checked and these countries do not exist in the country_list dataset.
Resolved to remove these from the co2 dataset.
# Drop countries from co2 data which do not have a corresponding record in the country_list dataset
co2 <- subset(co2, !(country_name %in% unmatched_round2$country_name.x))
# Combine the co2 emissions for countries with the same name but different codes
co2 <- co2 %>%
group_by(country_name, Year) %>%
summarise(co2 = sum(`Annual COâ‚‚ emissions (Global Carbon Project (2017)) (million tonnes)`))
LS0tCnRpdGxlOiAiQ08yIERhdGEgQ2xlYW5pbmciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KYGBge3J9CiMgSW1wb3J0IHJlcXVpcmVkIGxpYnJhcmllcwpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdndmlzKQpsaWJyYXJ5KGZ1enp5am9pbikKbGlicmFyeShqYW5pdG9yKQpgYGAKCgojIyBJbXBvcnQgQ1NWIGZpbGVzCmBgYHtyfQojIEltcG9ydCByYXcgQ1NWIGZpbGVzCmNvdW50cnlfbGlzdCA8LSByZWFkX2RlbGltKCcvVXNlcnMvdG9kZGRlcXVpbmNleS9Hb29nbGUgRHJpdmUvRWR1Y2F0aW9uICYgTGVhcm5pbmcvRGF0YSBTY2llbmNlL1VTUS9TZW1lc3RlciAyIDIwMTgvQ1NDODAwMiBCaWcgRGF0YSBNYW5hZ2VtZW50L1Byb2plY3QvRGF0YXNldHMvY2xlYW5lZF9kYXRhc2V0cy9jb3VudHJ5X2NsZWFuZWQuY3N2JywgZGVsaW09IiwiKQpjbzIgPC0gIHJlYWRfZGVsaW0oJy9Vc2Vycy90b2RkZGVxdWluY2V5L0dvb2dsZSBEcml2ZS9FZHVjYXRpb24gJiBMZWFybmluZy9EYXRhIFNjaWVuY2UvVVNRL1NlbWVzdGVyIDIgMjAxOC9DU0M4MDAyIEJpZyBEYXRhIE1hbmFnZW1lbnQvUHJvamVjdC9EYXRhc2V0cy91bmNsZWFuZWRfZGF0YXNldHMvYW5udWFsLWNvLWVtaXNzaW9ucy1wZXItY291bnRyeS5jc3YnLCBkZWxpbT0iLCIpCmBgYAoKIyMgRnV6enkgTWF0Y2gKSm9pbmluZyBvZiB0aGUgQ08yIGFuZCBjb3VudHJ5X2xpc3QgZGF0YXNldHMgYmFzZWQgb24gdGhlIGNvdW50cnkgbmFtZSBhdHRyaWJ1dGUgaW4gYm90aCBkYXRhc2V0cy4gIApBcyB0aGUgY291bnRyeSBuYW1lcyBtYXkgbm90IDEwMCUgbWF0Y2gsIGEgZnV6enkgbWF0Y2ggb2YgdGhlIGNvdW50cnkgbmFtZXMgYW5kIG1hbnVhbCBtYXBwaW5nIG9mIGFueSB1bm1hdGNoZWQgbmFtZXMgaXMgY29tcGxldGVkIHRvIGFsbG93IGZvciB0aGUgdHdvIGRhdGFzZXRzIHRvIGJlIHVzZWQgdG9nZXRoZXIuICAgCmBgYHtyfQojIFNldCBjb3VudHJ5IG5hbWVzIHRvIGxvd2VyIGluIGJvdGggZmlsZXMgdG8gYXZvaWQgY2FzZSBzZW5zaXRpdml0eQpjbzIkY291bnRyeV9uYW1lIDwtIHRvbG93ZXIoY28yJEVudGl0eSkKY291bnRyeV9saXN0JGNvdW50cnlfbmFtZSA8LSB0b2xvd2VyKGNvdW50cnlfbGlzdCRgQ09VTlRSWSBOQU1FYCkKYGBgCgoKYGBge3J9CiMgRnVuY3Rpb24gdG8gZnV6enkgbWF0Y2ggY291bnRyeSBuYW1lcwp1bm1hdGNoZWRfY291bnRyeV9uYW1lcyA8LSBmdW5jdGlvbihkZjEsIGRmMiwgY29sdW1uX25hbWUpewogIGRmMV9jb2wgPC0gdW5pcXVlKHNlbGVjdChkZjEsY29sdW1uX25hbWUpKQogIGRmMl9jb2wgPC0gdW5pcXVlKHNlbGVjdChkZjIsY29sdW1uX25hbWUpKQogIAogIG5hbWVfbWF0Y2hlcyA8LSBzdHJpbmdkaXN0X2xlZnRfam9pbih4ID0gZGYxX2NvbCwgeT0gZGYyX2NvbCwgbWF4X2Rpc3Q9MCkKICAKICAjIFJldHVybiBhbGwgcG9zaXRpdmUgbWF0Y2hlcyBmcm9tIGZ1enp5IGpvaW4gd2hpY2ggYXJlIE5PVCBleGFjdCBtYXRjaGVzCiAgcG9zaXRpdmVfbmFtZV9tYXRjaGVzIDwtIG5hbWVfbWF0Y2hlcyAlPiUgZmlsdGVyKGNvbXBsZXRlLmNhc2VzKC4pKQogIGZpbHRlcihwb3NpdGl2ZV9uYW1lX21hdGNoZXMsICEoMSA9PSAyKSkKICB1bm1hdGNoZWQgPC0gbmFtZV9tYXRjaGVzICU+JSBmaWx0ZXJfYWxsKGFueV92YXJzKGlzLm5hKC4pKSkKICByZXR1cm4odW5tYXRjaGVkKQp9CmBgYAoKYGBge3J9CiMgUmV0dXJuIGEgZGF0YWZyYW1lIG9mIGNvdW50cnkgbmFtZXMgd2hpY2ggZG8gbm90IG1hdGNoIGJldHdlZW4gY291bnRyeV9saXN0IGFuZCBjbzIgZGF0YXNldHMKdW5tYXRjaGVkIDwtIHVubWF0Y2hlZF9jb3VudHJ5X25hbWVzKGNvMixjb3VudHJ5X2xpc3QsICdjb3VudHJ5X25hbWUnKQp1bm1hdGNoZWQKYGBgCmByIGFzLmludGVnZXIoY291bnQodW5pcXVlKHVubWF0Y2hlZCkpKWAgcm93cyB3aXRoIHVubWF0Y2hlZCBuYW1lcy4gIApNYWpvcml0eSBvZiB0aGUgdW5tYXRjaGVkIGNvdW50cmllcyBhcmUgZWl0aGVyIHJlZ2lvbnMgb2YgdGhlIHdvcmxkIChlLmcuIHNvdXRoIGFtZXJpY2EpLCBjb3VudHJpZXMgd2l0aCBpc2xhbmQsIHNvdXRoLCBub3J0aCBvciBzYWludCBpbiB0aGVpciBuYW1lIG9yIG90aGVyIHJlY29yZHMgKGUuZy4gd29ybGQsIGFubmV4IGIpLCB3aGljaCBtYXkgaGF2ZSBiZWVuIGFiYnJldmlhdGVkIGluIHRoZSBjb3VudHJ5X2xpc3QgZGF0YXNldCAoZS5nLiBub3J0aCBtaWdodCBiZSBudGgpIG9yIGFyZSBpcnJlbHZhbnQgZm9yIG91ciBwdXJwb3Nlcy4gIApBbHNvIHNldmVyYWwgJ2FubmV4IGInIHR5cGVzLCB3aGljaCBhcmUgdW5rbm93bi4gIApBbGwgb2YgdGhlc2Ugbm9uLWNvdW50cnkgcmVjb3JkcyBhcmUgdG8gYmUgcmVtb3ZlZC4gCgpgYGB7cn0KIyBOb24tY291bnRyaWVzIGluIHVubWF0Y2hlZApub25fY291bnRyaWVzIDwtIGMoJ2FmcmljYScsICdhc2lhJywgJ2NlbnRyYWwgYW1lcmljYScsICdldTI4JywgJ2V1cm9wZScsICdrcCBhbm5leCBiJywgJ21pZGRsZSBlYXN0JywgJ25vbiBrcCBhbm5leCBiJywgJ25vbi1vZWNkJywgJ25vcnRoIGFtZXJpY2EnLCAnb2VjZCcsJ29jZWFuaWEnLCAnc3RhdGlzdGljYWwgZGlmZmVyZW5jZXMnLCAnd29ybGQnKQoKIyBDcmVhdGUgYSBzdWJzZXQgb2YgdGhlIGRhdGEgZXhjbHVkaW5nIHRoZSBub24tY291bnRyeSByZWNvcmRzCmNvMiA8LSBzdWJzZXQoY28yLCAhKGNvdW50cnlfbmFtZSAlaW4lIG5vbl9jb3VudHJpZXMpKQoKIyBHcm91cCBieSBjb3VudHJ5IG5hbWUgYW5kIHJldmlldyBmb3IgZnVydGhlciBub24tY291bnRyeSByZWNvcmRzCmNvMiAlPiUKICBncm91cF9ieShjb3VudHJ5X25hbWUpICU+JQogIHN1bW1hcmlzZSgpCmBgYAoKYGBge3J9CnVubWF0Y2hlZDIgPC0gdW5tYXRjaGVkX2NvdW50cnlfbmFtZXMoY28yLGNvdW50cnlfbGlzdCwgJ2NvdW50cnlfbmFtZScpCnVubWF0Y2hlZDIKYGBgCkFmdGVyIHJlLXJ1bm5pbmcgdGhlIG1hdGNoIG9uIHRoZSBjbGVhbmVkIGRhdGEsIHRoZXJlIGFyZSBub3cgYHIgYXMuaW50ZWdlcihjb3VudCh1bmlxdWUodW5tYXRjaGVkMikpKWAgY291bnRyaWVzIHdoaWNoIGRvIG5vdCBoYXZlIG1hdGNoZWQuICAKT3B0aW9ucyB0byBtYXRjaCB0aGVtIGNvdWxkIGluY2x1ZGUgcmVnZXggb3IgbW9yZSBkZXRhaWxlZCwgcHJlc2NyaXB0aXZlIGZ1enp5IG1hdGNoaW5nLCBob3dldmVyIGdpdmVuIHRoZXJlIGFyZSBvbmx5IGByIGFzLmludGVnZXIoY291bnQodW5pcXVlKHVubWF0Y2hlZDIpKSlgIHVubWF0Y2hlZCBjb3VudHJpZXMsIHJlc29sdmVkIHRvIG1hbnVhbCBtYXRjaCB0aGVtLiAgCgoKYGBge3J9CiMgTGlzdCBvZiB1bm1hdGNoZWQgY291bnRyaWVzIHdoaWNoIGhhdmUgYSBjb3JyZXNwb25kaW5nIHJlY29yZCBpbiB0aGUgY291bnRyeV9saXN0IGRhdGFzZXQKdW5tYXRjaGVkX2NvdW50cmllcyA9IGMoJ2N6ZWNob3Nsb3Zha2lhJywgJ2RlbW9jcmF0aWMgcmVwdWJsaWMgb2YgY29uZ28nLCAnZmFlcm9lIGlzbGFuZHMnLCAnZmFsa2xhbmQgaXNsYW5kcycsICdnYW1iaWEnLCAnbWljcm9uZXNpYSAoY291bnRyeSknLCAnbm9ydGgga29yZWEnLCAncGFsYXUnLCAncmV1bmlvbicsICdzYWludCBoZWxlbmEnLCAnc2FpbnQga2l0dHMgYW5kIG5ldmlzJywgJ3NhaW50IGx1Y2lhJywgJ3NhaW50IHBpZXJyZSBhbmQgbWlxdWVsb24nLCAnc2FpbnQgdmluY2VudCBhbmQgdGhlIGdyZW5hZGluZXMnLCAnc2ludCBtYWFydGVuIChkdXRjaCBwYXJ0KScsICdzb3V0aCBrb3JlYScsICdzb3V0aCBzdWRhbicsICd5dWdvc2xhdmlhJykKCiMgQSBsaXN0IG1hbnVhbGx5IG1hcHBpbmcgdGhlIHVubWF0Y2hlZCBjb3VudHJpZXMgdG8gdGhlIGNvdW50cnlfbGlzdCBkYXRhc2V0Cm1hbnVhbGx5X21hdGNoZWQgPC0gYygnY3plY2ggcmVwdWJsaWMnLCAnY29uZ28nLCAnZmFyb2UgaXNsYW5kcycsICdmYWxrbGFuZCBpc2xhbmRzIChpc2xhcyBtYWx2aW5hcyknLCAnZ2FtYmlhICB0aGUnLCAnbWljcm9uZXNpYSwgZmVkZXJhdGVkIHN0YXRlcyBvZicsICdrb3JlYSwgbm9ydGgnLCAncGFsYXUgLSB0cnVzdCB0ZXJyaXRvcnkgb2YgdGhlIHBhY2lmaWMgaXNsYW5kcycsICdyZXVuaW9uIGFuZCBhc3NvY2lhdGVkIGlzbGFuZHMnLCAnc3QuIGhlbGVuYScsICdzdC4ga2l0dHMgYW5kIG5ldmlzJywgJ3N0LiBsdWNpYScsICdzdC4gcGllcnJlIGFuZCBtaXF1ZWxvbicsJ3N0LiBsdWNpYSBhbmQgc3QuIHZpbmNlbnQnLCAnc3QuIG1hcnRlZW4sIHN0LiBldXN0YXRpdXMsIGFuZCBzYWJhJywgJ2tvcmVhLCBzb3V0aCcsICdzdWRhbicsICd5dWdvc2xhdmlhICgmIGZvcm1lciB0ZXJyaXRvcnkpJykKCgojIE1hcCBhbmQgdXBkYXRlIHRoZSBjb3VudHJ5IG5hbWVzIGluIGNvMiBkYXRhc2V0IHVzaW5nIHRoZSBtYW51YWxseV9tYXRjaGVkIG5hbWVzCmNvdW50IDwtIDEKZm9yIChjb3VudHJ5IGluIHVubWF0Y2hlZF9jb3VudHJpZXMpIHsKICBjbzIgPC0gY28yICU+JQogICAgbXV0YXRlKGNvdW50cnlfbmFtZSA9IGlmZWxzZSAoY291bnRyeV9uYW1lID09IGNvdW50cnksIGNvdW50cnlfbmFtZSA8LSBtYW51YWxseV9tYXRjaGVkW2NvdW50XSwgY28yJGNvdW50cnlfbmFtZSkpCiAgICBjb3VudCA8LSBjb3VudCArIDEKfQpgYGAKCgpgYGB7cn0KIyBSZXZpZXcgdGhlIHJlbWFpbmluZyB1bm1hdGNoZWQgY291bnRyaWVzCnVubWF0Y2hlZF9yb3VuZDIgPC0gdW5tYXRjaGVkX2NvdW50cnlfbmFtZXMoY28yLGNvdW50cnlfbGlzdCwgJ2NvdW50cnlfbmFtZScpCnVubWF0Y2hlZF9yb3VuZDIKYGBgCk1hbnVhbGx5IGNoZWNrZWQgYW5kIHRoZXNlIGNvdW50cmllcyBkbyBub3QgZXhpc3QgaW4gdGhlIGNvdW50cnlfbGlzdCBkYXRhc2V0LiAgClJlc29sdmVkIHRvIHJlbW92ZSB0aGVzZSBmcm9tIHRoZSBjbzIgZGF0YXNldC4gIAoKCmBgYHtyfQojIERyb3AgY291bnRyaWVzIGZyb20gY28yIGRhdGEgd2hpY2ggZG8gbm90IGhhdmUgYSBjb3JyZXNwb25kaW5nIHJlY29yZCBpbiB0aGUgY291bnRyeV9saXN0IGRhdGFzZXQKY28yIDwtIHN1YnNldChjbzIsICEoY291bnRyeV9uYW1lICVpbiUgdW5tYXRjaGVkX3JvdW5kMiRjb3VudHJ5X25hbWUueCkpCmBgYAoKCgpgYGB7cn0KIyBDb21iaW5lIHRoZSBjbzIgZW1pc3Npb25zIGZvciBjb3VudHJpZXMgd2l0aCB0aGUgc2FtZSBuYW1lIGJ1dCBkaWZmZXJlbnQgY29kZXMKY28yIDwtIGNvMiAlPiUKICBncm91cF9ieShjb3VudHJ5X25hbWUsIFllYXIpICU+JQogIHN1bW1hcmlzZShjbzIgPSBzdW0oYEFubnVhbCBDT+KCgiBlbWlzc2lvbnMgKEdsb2JhbCBDYXJib24gUHJvamVjdCAoMjAxNykpIChtaWxsaW9uIHRvbm5lcylgKSkKYGBgCgoKIyMgR2VuZXJhbCBEYXRhIENsZWFuaW5nCiMjIyMjIFJlbW92ZSBhbnkgZW1wdHkgcm93cyBhbmQgY29sdW1ucwpgYGB7cn0KIyBSZW1vdmUgcm93cyBhbmQgY29sdW1ucyB3aXRoIHRvdGFsbHkgZW1wdHkgdmFsdWVzIApyZW1vdmVfZW1wdHkoY28yLCAncm93cycpCnJlbW92ZV9lbXB0eShjbzIsICdjb2xzJykKYGBgCioqUmVzdWx0cyoqICAKTm8gZW1wdHkgcm93cyBvciBjb2x1bW5zIGZvdW5kLiBUaGVyZWZvcmUgbm8gY2hhbmdlcyB0byB0aGUgZGYKCgojIyMjIyBDaGVjayBmb3IgbWlzc2luZyB2YWx1ZXMKYGBge3J9CiMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzIC8gbnVsbHMgb24ga2V5IAphbnlOQShjbzIpCmBgYAoqKlJlc3VsdHMqKiAgCk5vIG1pc3NpbmcgdmFsdWVzIGlkZW50aWZpZWQuCgoKIyMjIyMgQ2hlY2sgZm9yIG5lZ2F0aXZlIENPMiBlbWlzc2lvbiB2YWx1ZXMKYGBge3J9CiMgUmV0dXJuIHRoZSBtaW5pbXVtIHZhbHVlIGZvciBDTzIgZW1pc3Npb25zIGNvbHVtbgptaW4oY28yWywzXSkKYGBgCioqUmVzdWx0cyoqICAKTWluaW11bSB2YWx1ZSBpbiBjbzJfZW1pc3Npb25zIGNvbHVtbiBpcyBgciBtaW4oY28yWywzXSlgLiBUaGVyZWZvcmUsIG5vIG5lZ2F0aXZlIHZhbHVlcy4KCgojIyMjIyBDaGVjayB5ZWFyIHJhbmdlIGlzIGNvcnJlY3QKYGBge3J9CiMgUmV0dXJuIHRoZSBtaW5pbXVtIHllYXIgdmFsdWUKbWluX3llYXIgPC0gbWluKGNvMlssMl0pCm1heF95ZWFyIDwtICBtYXgoY28yWywyXSkKbWluX3llYXIKbWF4X3llYXIKYGBgCioqUmVzdWx0cyoqICAKTWluaW11bSB2YWx1ZSBpbiB0aGUgeWVhciBjb2x1bW4gaXMgYHIgbWluX3llYXJgLCB3aXRoIGEgbWF4aW11bSBvZiBgciBtYXhfeWVhcmAuICAKVmFsdWVzIGFyZSB3aXRoaW4gZXhwZWN0ZWQgcmFuZ2UuCgoKIyMgRXhwb3J0IHJlc3VsdHMgdG8gQ1NWCmBgYHtyfQojIFdyaXRlIGNsZWFuZWQgZGF0YSBiYWNrIHRvIGNzdiBmb3IgaW1wb3J0IGludG8gTXlTUUwKd3JpdGVfY3N2KGNvMiwgJy9Vc2Vycy90b2RkZGVxdWluY2V5L0dvb2dsZSBEcml2ZS9FZHVjYXRpb24gJiBMZWFybmluZy9EYXRhIFNjaWVuY2UvVVNRL1NlbWVzdGVyIDIgMjAxOC9DU0M4MDAyIEJpZyBEYXRhIE1hbmFnZW1lbnQvUHJvamVjdC9EYXRhc2V0cy9jbGVhbmVkX2RhdGFzZXRzL2NvMl9jbGVhbmVkLmNzdicpCmBgYAoKCgoK