在 rworldmap 中查看 joinCountryData2Map 的不匹配国家?

See unmatched countries for joinCountryData2Map in rworldmap?

我正在使用 rworldmap 中的 joinCountryData2Map 函数将我的数据与世界地图上的国家相匹配。

我得到这个结果:

230 codes from your data successfully matched countries in the map
11 codes from your data failed to match with a country code in the map
11 codes from the map weren't represented in your data

我不知道如何查看这两个包含 11 个国家/地区的列表。我猜测这 11 个国家/地区的 ISO2 代码存在问题,我需要更正这些代码,但我不确定在无法查看这两个列表的情况下检查哪些。

我猜想有一个解决方案只是 View(SomeObject$Countries),但我没能找到任何有效的方法。

设置joinCountryData2Map(...,verbose=TRUE)在控制台打印匹配失败的国家名称。

From the FAQ: "您可以看到成功加入的国家/地区的摘要输出到控制台。您可以指定 verbose=TRUE 以获取完整的国家/地区列表"

library(rworldmap)

data(countryExData)

# Set Angola to fail
countryExData[countryExData$ISO3V10 == "AGO", "ISO3V10"] <- "AGO_FAIL"

# Attempt to join
# With verbose=TRUE, failed joins (ie Angola) are printed in the console
sPDF <- joinCountryData2Map(
  countryExData[,c("ISO3V10", "Country")],
  joinCode = "ISO3",
  nameJoinColumn = "ISO3V10",
  verbose = TRUE)

# > 148 codes from your data successfully matched countries in the map
# > 1 codes from your data failed to match with a country code in the map
# >      failedCodes failedCountries
# > [1,] "AGO_FAIL"  "Angola"       
# > 95 codes from the map weren't represented in your data

但是,如果您想以编程方式获取有关失败连接的信息怎么办?我可能错过了一些东西,但我没有看到相应的选项(即 str(sPDF) 或函数参数)。但是,查看 joinCountryData2Map() 的内部结构,对象 failedCountries 包含您想要的信息,因此将它包含在 returned 对象中应该很容易。

以下是将包含两个元素的列表 joinCountryData2Map() 修改为 return 的方法:第一个元素是默认对象,第二个元素是 failedCountries.

# Modify the function to return the failed joins in the environment
joinCountryData2Map_wfails <- function(
  dF, joinCode = "ISO3", nameJoinColumn = "ISO3V10",
  nameCountryColumn = "Country", suggestForFailedCodes = FALSE, 
  mapResolution = "coarse", projection = NA, verbose = FALSE) {
  
  # Retain successful join as first element and failed join as second element
  ll <- list() # MODIFIED
  mapWithData <- getMap(resolution = mapResolution)
  if (!is.na(projection)) 
    warning("the projection argument has been deprecated, returning Lat Lon, use spTransform from package rgdal as shown in help details or the FAQ")
  listJoinCodesNew <- c("ISO_A2", "ISO_A3", "FIPS_10_", 
                        "ADMIN", "ISO_N3")
  listJoinCodesOld <- c("ISO2", "ISO3", "FIPS", 
                        "NAME", "UN")
  listJoinCodes <- c(listJoinCodesOld, listJoinCodesNew)
  if (joinCode %in% listJoinCodes == FALSE) {
    stop("your joinCode (", joinCode, ") in joinCountryData2Map() is not one of those supported. Options are :", 
         paste(listJoinCodes, ""), "\n")
    return(FALSE)
  }
  joinCodeOld <- joinCode
  if (joinCode %in% listJoinCodesOld) {
    joinCode <- listJoinCodesNew[match(joinCode, listJoinCodesOld)]
  }
  if (is.na(match(nameJoinColumn, names(dF)))) {
    stop("your chosen nameJoinColumn :'", nameJoinColumn, 
         "' seems not to exist in your data, columns = ", 
         paste(names(dF), ""))
    return(FALSE)
  }
  dF[[joinCode]] <- as.character(dF[[nameJoinColumn]])
  dF[[joinCode]] <- gsub("[[:space:]]*$", "", dF[[joinCode]])
  if (joinCode == "ADMIN") {
    dF$ISO3 <- NA
    for (i in 1:nrow(dF)) dF$ISO3[i] = rwmGetISO3(dF[[joinCode]][i])
    joinCode = "ISO3"
    nameCountryColumn = nameJoinColumn
  }
  matchPosnsInLookup <- match(as.character(dF[[joinCode]]), 
                              as.character(mapWithData@data[[joinCode]]))
  failedCodes <- dF[[joinCode]][is.na(matchPosnsInLookup)]
  numFailedCodes <- length(failedCodes)
  numMatchedCountries <- nrow(dF) - numFailedCodes
  cat(numMatchedCountries, "codes from your data successfully matched countries in the map\n")
  failedCountries <- dF[[nameCountryColumn]][is.na(matchPosnsInLookup)]
  failedCountries <- cbind(failedCodes, failedCountries = as.character(failedCountries))
  cat(numFailedCodes, "codes from your data failed to match with a country code in the map\n")
  if (verbose) 
    print(failedCountries)
  matchPosnsInUserData <- match(as.character(mapWithData@data[[joinCode]]), 
                                as.character(dF[[joinCode]]))
  codesMissingFromUserData <- as.character(mapWithData@data[[joinCode]][is.na(matchPosnsInUserData)])
  countriesMissingFromUserData <- as.character(mapWithData@data[["NAME"]][is.na(matchPosnsInUserData)])
  numMissingCodes <- length(codesMissingFromUserData)
  cat(numMissingCodes, "codes from the map weren't represented in your data\n")
  mapWithData@data <- cbind(mapWithData@data, dF[matchPosnsInUserData, 
  ])
  invisible(mapWithData)
  
  ll[[1]] <- mapWithData # MODIFIED
  ll[[2]] <- failedCountries # MODIFIED
  return(ll) # MODIFIED
}

用法:

sPDF_wfails <- joinCountryData2Map_wfails(
  countryExData[,c("ISO3V10", "Country")],
  joinCode = "ISO3",
  nameJoinColumn = "ISO3V10",
  verbose = TRUE)

# This is the result of the original function
# sPDF_wfails[[1]]

# This is info on the failed joins
sPDF_wfails[[2]]

# >     failedCodes failedCountries
# > [1,] "AGO_FAIL"  "Angola"