Doubt about the function joinCountryData2Map

Hello, I am starting to work with R, but some problems came up, perhaps someone with more experience could help me with the following problem...

I am working on a project that should plot a heat map from a database that I've created, but I am not able to make the joinCountryData2Map work as expected.

In my project, I have to aggregate some columns and apply some functions to find a coefficient, when I have it, I create a table with a meaningful column for the project plus the coefficient that I have found.

Once I have the resulting table I try to use it in the joinCountryData2Map function, but the following error appears:

Error in joinCountryData2Map(tableResult, nameJoinColumn = "coefficient",  : 
  your chosen nameJoinColumn :'coefficient' seems not to exist in your data, columns = 

I don't know why it said that coefficient' seems not to exist in my data, because it is in the table...

My code:

dados = read.csv2("C:\\Users\\codewraith\\Desktop\\data.csv" , sep="," , dec=".")

coefficients = apply(dados, 1, processRow)
coef_country <- cbind(as.character(dados$country), as.numeric(coefficients))
colnames(coef_country) <- c("country", "coefficient")
tableResult <- as.table(coef_country)
tableResult

# MAP part
df<-head(tableResult)
kable(df) %>%
kable_styling(bootstrap_options = "striped", font_size= 10, full_width = F)

#join data to a map
print(colnames(tableResult))
class(tableResult)
# The problem is right here (parameter tableResult)
WorldMapSurvivalRate <- joinCountryData2Map( tableResult,
                                               nameJoinColumn="coefficient",
                                               joinCode="NAME" )

#Set the color palette with RColorBrewer:
colourPalette <- RColorBrewer::brewer.pal(10,'Spectral') #'Purples'
#plot the map
mapCountryData( WorldMapSurvivalRate,
                nameColumnToPlot='Survival Rate',
                catMethod='fixedWidth',
                colourPalette=colourPalette, #'diverging', 'heat'
                numCats=100) #10

This is the print of the table:

Can't I use a table as a parameter in the function joinCountryData2Map?

How can I solve this problem?

I would really appreciate if someone could help me with this problem.

Thank you!

Are you talking about the joinCountryData2Map() function from the rworldmap package?
If so, this function requeries as input a dataframe not a table and the nameJoinColumn parameter should be the name of the column containing country referencing not the coefficient.

It would be easier to help you if you could ask this with a minimal REPRoducible EXample (reprex). A reprex makes it much easier for others to understand your issue and figure out how to help.

If you've never heard of a reprex before, you might want to start by reading this FAQ:

How can I transform the table into a dataframe?

I think the table and the wrong name are the problems.

I can't be sure without sample data but maybe this would work

df <- as.data.frame(coef_country)

My code:

### Load the package or install if not present
if (!require("rworldmap")) {
    install.packages("rworldmap")
    library(rworldmap)
}

if (!require("RColorBrewer")) {
    install.packages("RColorBrewer")
    library(RColorBrewer)
}

if (!require("kableExtra")) {
    install.packages("kableExtra")
    library(kableExtra)
}

dangerousness <- function(arg) {
    if(arg == "High")
        return(0.6)
    if(arg == "Medium")
        return(0.8)
    if(arg == "Low")
        return(1)
}

guns <- function(arg) {
    if(arg == "High")
        return(1)
    if(arg == "Medium")
        return(0.75)
    if(arg == "Low")
        return(0.5)
}

ally <- function(arg) {
    return(0.6 + (0.4 * as.numeric(sub("%", "", arg))/100))
}

dog <- function(arg) {
    if(arg == "High")
        return(1)
    if(arg == "Medium")
        return(0.7)
    if(arg == "Low")
        return(0.4)
}

processRow <- function(row) {
    coef_dang = dangerousness(row['dangerousness'])
    coef_guns = guns(row['qtd_guns'])
    coef_ally = ally(row['influence_in_the_region'])
    coef_dog = dog(row['dog_food_availability'])
    return(coef_dang * coef_guns * coef_ally * coef_dog)
}

data = read.csv2("C:\\Users\\codewraith\\Desktop\\data.csv" , sep="," , dec=".")

coefficients = apply(data, 1, processRow)
coef_country <- cbind(as.character(data$country), as.numeric(coefficients))
colnames(coef_country) <- c("country", "coefficient")
tableResult <- as.table(coef_country)
#tableResult

#Convert 
tableAsDataframe = as.data.frame(tableResult)
tableAsDataframe


# MAP part
df<-head(tableResult)
kable(df) %>%
kable_styling(bootstrap_options = "striped", font_size= 10, full_width = F)

#join data to a map
print(colnames(tableResult))
class(tableResult)
WorldMapSurvivalRate <- joinCountryData2Map( tableResult,
                                               nameJoinColumn="country",
                                               joinCode="NAME" )

#Set the color palette with RColorBrewer:
colourPalette <- RColorBrewer::brewer.pal(10,'Spectral') #'Purples'
#plot the map
mapCountryData( WorldMapSurvivalRate,
                nameColumnToPlot='Survival Rate',
                catMethod='fixedWidth',
                colourPalette=colourPalette, #'diverging', 'heat'
                numCats=100) #10

Dataset:
I am not able to upload the .csv :neutral_face: so I will put here some of the rows:

country,shelter,ally,influence_in_the_region,dog_food_availability,qtd_guns,assassin_name,dangerousness
Russia,Av del Matador 432,The Terminator,10.00%,High,Low,Alex Delarge,High
United States of America,Hollywood Street 6500,Rocky Balboa,12.00%,Low,High,Patrick Bateman,Low
Italy,V Settimo Torinese,Vito Corleone,5.00%,Medium,Low,The Joker,Medium
South Korea,Gyeonggi-do 537,Deadpool,4.00%,Medium,Medium,Freddy Krueger,Medium
El Salvador,Calle los Pozos 45,Martin Riggs,65.00%,Low,High,Agent Smith,High
Austria,Stephansplatz 5010,Buzz Lightyear,32.00%,High,Medium,Boba Fett,Low
Germany,Str Baunatal 325,Wolverine,11.00%,Medium,Low,The Man With No Name,Low
France,Route de Hyds 566,V,3.00%,High,High,Jigsaw,High
England,Green Street 32,Ace Ventura,4.00%,Medium,Medium,Jason,Low

I tried to convert to a dataframe but this happened:

It added country and coefficient in the rows... it should maintain them as columns :sweat_smile:. I tried to convert the final table into dataframe...

tableAsDataframe = as.data.frame(tableResult)

There is no need for sharing the csv file itself, you can share sample data as simply as running this code and pasting the result here.

data = read.csv2("C:\\Users\\codewraith\\Desktop\\data.csv" , sep="," , dec="."
datapasta::df_paste(data)

Here is a nice blog post by Mara that explains how to use datapasta package for sharing sample data on a copy/paste friendly format.

The data:

data.frame(
country = as.factor(c("Russia", "United States of America",
"Italy", "South Korea", "El Salvador",
"Austria", "Germany", "France",
"England", "Canada", "Brazil", "Spain",
"Colombia", "Panama", "Japan", "Croatia",
"Netherlands", "Uruguay", "Norway", "Peru",
"Switzerland", "Portugal", "Egypt",
"Mexico", "South Africa", "China", "Poland",
"Malaysia", "Chile")),
shelter = as.factor(c("Av del Matador 432",
"Hollywood Street 6500",
"V Settimo Torinese", "Gyeonggi-do 537",
"Calle los Pozos 45", "Stephansplatz 5010",
"Str Baunatal 325", "Route de Hyds 566",
"Green Street 32", "R de la Reine 320",
"R Salvador 441", "Str del Ramirez 1623",
"Str del Silencio", "Str Plaza Fidanque",
"Av Fukuoka 674", "R Rijeka 308",
"Av Willem Dreesweg 1188",
"Str de los suspiros 38", "V Salgs 1904", "Av Arequipa 5428",
"Av Hauptstrasse 585",
"R Casabranca 351", "Soud Street", "Calle 5 de Mayo 706",
"Str Mist Hill 125", "Av Beijing",
"R Kielbasnicza 32", "Av Banting 9",
"Str Royal Palace 519")),
ally = as.factor(c("The Terminator", "Rocky Balboa",
"Vito Corleone", "Deadpool",
"Martin Riggs", "Buzz Lightyear", "Wolverine",
"V", "Ace Ventura", "Frank Drebin",
"Tony Stark", "Blade", "Peter Venkman",
"Marty McFly", "Jason Bourne",
"Harry Callahan", "Rambo", "Forrest Gump", "Neo",
"John McClane", "James Bond", "Ellen Ripley",
"Jack Sparrow",
"Indiana Jones", "Tyler Durden", "Zorro",
"Rick Blaine", "T. E. Lawrence", "Punisher")),
influence_in_the_region = as.factor(c("10.00%", "12.00%", "5.00%", "4.00%",
"65.00%", "32.00%", "11.00%", "3.00%",
"4.00%", "54.00%", "1.00%", "31.00%",
"6.00%", "33.00%", "77.00%", "91.00%",
"86.00%", "5.00%", "99.00%", "20.00%",
"53.00%", "87.00%", "55.00%", "4.00%",
"23.00%", "71.00%", "23.00%", "43.00%",
"60.00%")),
dog_food_availability = as.factor(c("High", "Low", "Medium", "Medium",
"Low", "High", "Medium", "High",
"Medium", "Low", "Medium", "Low", "High",
"Medium", "Low", "High", "Medium", "High",
"Medium", "Low", "High", "Medium",
"Low", "High", "Medium", "Low", "High",
"Medium", "Low")),
qtd_guns = as.factor(c("Low", "High", "Low", "Medium",
"High", "Medium", "Low", "High",
"Medium", "High", "Low", "Medium", "High",
"Low", "High", "Medium", "High", "Low",
"Medium", "High", "Low", "Medium", "Low",
"High", "Low", "Medium", "Medium",
"High", "Low")),
assassin_name = as.factor(c("Alex Delarge", "Patrick Bateman",
"The Joker", "Freddy Krueger",
"Agent Smith", "Boba Fett",
"The Man With No Name", "Jigsaw", "Jason",
"Michael Corleone", "Jules Winnfield", "Hans Gruber",
"Gollum", "Dr. Hannibal Lecter",
"Darth Vader", "Dracula", "Norman Bates",
"Alex Forrest", "Regan MacNeil", "Amon Gaoth",
"Annie Wilkes", "Tony Camonte",
"Verbal Kint", "Tom Powers",
"Auric Goldfinger", "Max Cady", "Phyllis Dietrichson",
"J.J. Hunsecker", "Frank Booth")),
dangerousness = as.factor(c("High", "Low", "Medium", "Medium",
"High", "Low", "Low", "High", "Low",
"Low", "High", "Medium", "Medium",
"High", "High", "Medium", "Low", "Medium",
"Low", "Low", "Low", "Medium", "Medium",
"Medium", "High", "High", "High", "Low",
"Low"))
)

Now I have changed, instead of creating the table then converting it, I went straight for the conversion and it worked, but the legend got quite weird, how can I put like green for good, yellow for medium and red for bad?

image

This doesn't make much sense with the data the as it is rigth now, because you want to assign a discrete scale (good, medium, bad) to a continuos variable (coefficients), but if you define what the midpoint of your gradient scale is, you could do something like this example.

coef_country <- data.frame(
    country = c("Russia", "United States of America", "Italy",
                "South Korea", "El Salvador", "Austria",
                "Germany", "France", "England", "Canada", "Brazil", "Spain",
                "Colombia", "Panama", "Japan", "Croatia",
                "Netherlands", "Uruguay", "Norway", "Peru", "Switzerland",
                "Portugal", "Egypt", "Mexico", "South Africa", "China",
                "Poland", "Malaysia", "Chile"),
    coefficient = c(0.19, 0.2592, 0.1736, 0.25872, 0.2064,
                    0.546, 0.2254, 0.3672, 0.3234, 0.3264,
                    0.12684, 0.17376, 0.4992, 0.15372, 0.21792,
                    0.5784, 0.6608, 0.248, 0.5229, 0.272,
                    0.406, 0.39816, 0.1312, 0.4928, 0.14532,
                    0.15912, 0.3114, 0.5404, 0.168)
)

library(tidyverse)
library(rnaturalearth)
library(rnaturalearthdata)

world <- ne_countries(scale = "medium", returnclass = "sf") %>% 
    left_join(coef_country, by = c("name" = "country"))

ggplot(world) +
    geom_sf(aes(fill = coefficient))+
    scale_fill_gradient2(low = "blue",
                         mid = "yellow",
                         high = "red", midpoint = 0.4)

This error is happening:

How can I solve it?

It's hard to help you with a screenshot please make your questions with a proper reproducible example, also this question is very different from the original one, you should ask it on a new topic.

I added your code to see how it would represent the data... so it is the same problem, not a different one... I am trying to represent my data using the libraries that you proposed... but it is not working... if you want the "code" it is the code that you used in your example:

data = read.csv2("C:\\Users\\codewraith\\Desktop\\data.csv" , sep="," , dec=".")
#datapasta::df_paste(data)

coefficients = apply(data, 1, processRow)
coef_country <- cbind(as.character(data$country), as.numeric(coefficients))
colnames(coef_country) <- c("country", "survival rate")
tableResult <- as.data.frame(coef_country)

world <- ne_countries(scale = "medium", returnclass = "sf") %>% 
    left_join(coef_country, by = c("name" = "country"))

ggplot(world) +
    geom_sf(aes(fill = coefficient))+
    scale_fill_gradient2(low = "blue",
                         mid = "yellow",
                         high = "red", midpoint = 0.4)

Your original question (the one in the title) is about the joinCountryData2Map() function from the rworldmap package, know you are asking how to adapt my example with ggplot2 to your own data, and a reproducible example is not just posting any chunk of code, you have to put together sample data and code that reproduces your issue.

Well forget it, thanks for your help.

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.