For a group project, I wanted to create a interactive Europe map, based on this data set: https://ourworldindata.org/causes-of-death.
I have manage to create this map, which will display the number of deaths caused by drowning in 2019 in Europe. But I would like to create an interactive map where the user could enter the cause of deaths for example HIV or Fire, so that the map could display it. I have tried to use an input but it doesn't work and shows me this error message : "Error in : Discrete value supplied to continuous scale". I know that the cause of this issue is the fact that the parameter size is a int but the input a char.
Unfortunalty I don't know how to correct this issue :(
Can anyone help me with it?
Have a nice day,
AM.
library("maptools")
library(rgdal)
library(maps)
library("jsonlite")
library(RColorBrewer)
library(ggmap)
rowdb <- read.csv("annual-number-of-deaths-by-cause.csv", sep = ';')
rowdb <- select(rowdb, -X.1, -X)
europe <- c(left = -12, bottom = 35, right = 30, top = 63)
map_E <- get_stamenmap(europe, zoom = 5,"toner-lite")
ggmap(map_E)
#On va cr?er une variable contenant les noms des pays du continent puis pour une date donn?e
#qu'on pourra aussi demander ? l'utilisateur de s?lectionner on affichera la carte du
#continent et la cause choisies
Europe_E <- c("Albania", "Andorra", "Armenia", "Austria","Azerbaijan","Belarus",
"Belgium", "Bosnia and Herzegovina", "Bulgaria", "Croatia","Cyprus",
"Czechia", "Denmark", "Estonia", "Finland", "France", "Georgia",
"Germany", "Greece", "Hungary", "Iceland", "Ireland", "Italy",
"Kazakhstan","Latvia", "Lithuania", "Luxembourg", "Malta", "Moldova", "Monaco",
"Montenegro", "Netherlands","North Macedonia", "Norway", "Poland", "Portugal",
"Romania", "Russia", "San Marino","Serbia", "Slovakia", "Slovenia", "Spain",
"Sweden", "Switzerland", "Turkey", "Ukraine", "United Kingdom")
#Fonction pour avoir la latitude et longitude des pays
if (!(require(jsonlite))) install.packages("jsonlite")
mygeocode <- function(adresses){
# adresses est un vecteur contenant toutes les adresses sous forme de chaine de caracteres
nominatim_osm <- function(address = NULL){
## details: http://wiki.openstreetmap.org/wiki/Nominatim
## fonction nominatim_osm propos?e par D.Kisler
if(suppressWarnings(is.null(address))) return(data.frame())
tryCatch(
d <- jsonlite::fromJSON(
gsub('\\#addr\\#', gsub('\\s+', '\\%20', address),
'http://nominatim.openstreetmap.org/search/#addr#?format=json&addressdetails=0&limit=1')
), error = function(c) return(data.frame())
)
if(length(d) == 0) return(data.frame())
return(c(as.numeric(d$lon), as.numeric(d$lat)))
}
tableau <- t(sapply(adresses,nominatim_osm))
colnames(tableau) <- c("lon","lat")
return(tableau)
}
latlon_E <- mygeocode(Europe_E)
#is(lalo)
dat_E <- as.data.frame(latlon_E)
DAT_E <- rowdb
DAT_E$Year <- year(as.Date(DAT_E$Year, format = "%Y"))
DAT_E <- DAT_E[
as.character(DAT_E$Year) %in% c("2019"), ]
DAT_E <- DAT_E[
DAT_E$Entity %in% Europe_E, ]
ggmap(map_E, extent = "device") +
geom_point(data = DAT_E, aes(x = dat_E$lon , y =dat_E$lat, color = Europe_E, size = Drowning), alpha = 0.5) +
geom_text(data = DAT_E, aes(x = dat_E$lon, y = dat_E$lat, label = Drowning), color = "black", size = 3.7) +
scale_size_continuous(range = c(6, 12)) + theme(legend.position = "none")+
facet_wrap(~ Year)
Related
Is it possible in Shiny to filter one variable of a dataframe based on an externally defined vector, which can be selected as an input?
The minimum reproducible example demonstrates the problem. Running the code, you will see that the output table is empty.
When I replace the input$region value with one of the vectors that can be selected, it works. So I guess that the problem is in how the radioButtons input or selectInput returns the vector.
I have studied the documentation for selectInput on cran which suggests that it is possible to group: "" #param choices List of values to select from. If elements of the list are
named, then that name --- rather than the value --- is displayed to the
user. It's also possible to group related inputs by providing a named list
whose elements are (either named or unnamed) lists, vectors, or factors. In
this case, the outermost names will be used as the group labels (leveraging
the <optgroup> HTML tag) for the elements in the respective sublist. See
the example section for a small demo of this feature.
The following stackoverflow QAs Dependent filter in shiny inputs and Filtering from selected input in R shiny address some issues, but they do not answer the same problem, as they filter the variable based on values extracted from the unique values of the variable itself.
Below a minimum reproducible example.
#library(dplyr)
#library(shiny)
#Sample data
Country <- c("Finland", "Estonia", "Kuwait", "Germany", "Italy", "Belgium", "Ukraine", "Belgium", "Italy", "Italy", "Belarus", "Turkey", "Italy", "Switzerland", "Turkey", "France", "Turkey", "Denmark", "Latvia", "United Arab Emirates", "Spain")
Organisation <- c("FIN", "LOT", "KAC", "EZY", "RYR", "BEL", "MSI", "RYR", "AZA", "RYR", "BRU", "THY", "AZA", "EZS", "THY", "TVF", "PGT", "SAS", "BTI", "UAE", "RYR")
Operations <- c(10, 2, 1, 50, 32, 18, 12, 63, 41, 1, 13, 15, 28, 33, 14, 8, 11, 52, 27, 2, 19)
test_data <- data.frame(Country, Organisation, Operations)
Europe <- c("Finland", "Estonia", "Germany", "Italy", "Belgium", "Belarus", "Turkey", "Switzerland", "Denmark", "Latvia", "Spain")
EU <- c("Finland", "Estonia", "Germany", "Italy", "Belgium", "Denmark", "Latvia", "Spain")
#Shiny
# UI
ui <- fluidPage(
radioButtons("region", "Select Departure Region",
choices = c("Europe", "EU")),
# selectInput("region", "Select a Departure Region",
# list('Europe' = list("Finland", "Estonia", "Germany", "Italy", "Belgium", "Belarus", "Turkey", "Switzerland", "Denmark", "Latvia", "Spain"),
# 'EU'= list("Finland", "Estonia", "Germany", "Italy", "Belgium", "Denmark", "Latvia", "Spain"))
# ), #Is the problem that the vector is not correctly defined when selected? However, even creating a list does not result in the same output, as a normal dplyr %in% filter
tableOutput("Market_Table")
)
server <- function(input, output) {
#Does not work; though works if I use the Vector in place of the input variable
# filtered_data <- reactive({
# test_data[test_data$Country %in% input$region, ] .
# })
filtered_data <- reactive({
test_data %>% filter(Country %in% input$region) #Should some sort of reference to .env be used? .env$input$region however does not work.
})
#suggested in Mastering Shiny chapter 12.2.1 but also does not correctly filter - nothing appears in the table
# filtered_data <- reactive({
# test_data[test_data$Country %in% input$region, ]
# })
output$Market_Table <- renderTable({filtered_data()})
}
# Run the application
shinyApp(ui = ui, server = server)
Calling input$region is returning the selected object's name as a string. Use the get() function to return the values of a named object:
...
server <- function(input, output) {
filtered_data <- reactive({
test_data %>% filter(Country %in% get(input$region))
})
...
using leaflet package to create interactive map using r shiny. my dataset provides the names of countries but not the lat or long. how can i create this where the map can detect by country names
You can use a geojson map with the readOGR function, you can find the map on internet and link your dataset to it.
rgdal::readOGR(dsn = "GeoJSON map",
layer = "OGRGeoJSON",
stringsAsFactors = FALSE)
Below is an example based on this stackoverflow post to make an interactive map on R Shiny. The selected countries are in click.list$ids, see the output$selected_var below.
Your data
## packages ##
packages <- c("leaflet", "shiny", "shinydashboard")
newPackages <- packages[!(packages %in% installed.packages()[,"Package"])]
if(length(newPackages)) install.packages(newPackages)
lapply(packages, library, character.only = TRUE)
remove(packages, newPackages)
## map & data ##
Europe <- rgdal::readOGR(dsn = "https://data.opendatasoft.com/explore/dataset/european-union-countries#public/download/?format=geojson&timezone=Europe/Berlin",
layer = "OGRGeoJSON",
stringsAsFactors = FALSE)
data <- data.frame("name" = c("Austria", "Belgium", "Bulgaria", "Croatia", "Cyprus", "Czechia", "Denmark", "Estonia",
"Finland", "France", "Germany", "Greece", "Hungary", "Iceland", "Ireland", "Italy", "Latvia",
"Liechtenstein", "Lithuania", "Luxembourg", "Malta", "Netherlands", "Norway", "Poland", "Portugal",
"Romania", "Slovakia", "Slovenia", "Spain", "Sweden", "Switzerland", "Turkey", "United Kingdom"),
"polcapita" = c(0.0087928207, 0.0100464969, 0.0075375536, 0.0049040898, 0.0097860082, 0.0119440135, 0.0087740252,
0.0080851042, 0.0063462331, 0.0064707328, 0.0107846429, 0.0085740997, 0.0059612600, 0.0409884683,
0.0138830047, 0.0067616652, 0.0049423915, 0.0053782730, 0.0053461017, 0.0165884166, 0.0046052235,
0.0116079951, 0.0052533159, 0.0100049243, 0.0075509189, 0.0047028415, 0.0067531703, 0.0077087169,
0.0064795469, 0.0008881585, 0.0053907055, 0.0053085690, 0.0069728195))
# example if you need to change the name of a country
Europe#data[Europe#data$name == "Czech Rep.", ]$name <- "Czechia"
# example if you want to add datas to the map
Europe#data$polcapita <- merge(x = Europe#data, y = data, sort = FALSE)$polcapita
pal <- colorNumeric(c("Green", "Red"), Europe$polcapita)
The UI part
## create the UI ##
ui <- fluidPage(
# place the contents inside a box
shinydashboard::box(
width = 12,
title = "Click on the map!",
# separate the box by a column
column(width = 2,
shiny::actionButton(inputId = "clearHighlight",
icon = icon( name = "eraser"),
label = "Clear the Map",
style = "color: #fff; background-color: #D75453; border-color: #C73232")),
# separate the box by a column
column(width = 10,
leaflet::leafletOutput(outputId = "myMap", height = 850)),
column(width = 5,
textOutput("selected_var"))
)
)
The server part
## create the server ##
server <- function( input, output, session ){
# create foundational map
foundational.map <- shiny::reactive({
leaflet(Europe) %>%
fitBounds(-20, 65, 20, 39) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addPolygons(data = Europe,
layerId = Europe$name,
color = ~pal(polcapita),
group = "click.list",
weight = 2,
fillOpacity = 0.3,
opacity = 1,
smoothFactor = 0.2,
stroke = FALSE)
})
output$myMap <- renderLeaflet({
foundational.map()
})
# store the list of clicked polygons in a vector
click.list <- shiny::reactiveValues(ids = vector())
# add countries to selection
shiny::observeEvent(input$myMap_shape_click, {
click <- input$myMap_shape_click
if(click$id %in% click.list$ids){
click.list$ids <- click.list$ids[!click.list$ids%in%click$id]
leaflet::leafletProxy(mapId = "myMap") %>%
clearGroup("lin")
} else{
click.list$ids <- c(click.list$ids, click$id)
}
lines.of.interest <- Europe[ which(Europe$name %in% click.list$ids), ]
leaflet::leafletProxy(mapId = "myMap") %>%
addPolylines(data = lines.of.interest,
layerId = lines.of.interest$ids,
color = "#6cb5bc",
weight = 2,
opacity = 1,
group = "lin")
})
# Clear the map button
shiny::observeEvent( input$clearHighlight, {
output$myMap <- leaflet::renderLeaflet({
click.list$ids <- NULL
foundational.map()
})
})
# selected countries
output$selected_var <- renderText({
paste("You have selected", click.list$ids)
})
}
To run the server
## run shinyApp ##
shiny::shinyApp(ui, server)
I hope it answers your question !
I am trying to map a bunch of countries with the following code.
require(mapdata)
# get the names
cc <- map('world', names = TRUE, plot = FALSE)
take <- unlist(sapply(c("iran", "malaysia", "saudi arabia", "united arab emirates", "kuwait", "bahrain", "indonesia", "qatar", "sudan", "pakistan", "bangladesh", "turkey", "egypt", "united kingdom", "jordan", "brunei", "sri lanka", "oman", "yemen", "lebanon", "kenya"), grep, tolower(cc), value = TRUE))
suppressWarnings(map())
suppressWarnings(map('world', regions=take, fill=TRUE, col='red', add = TRUE))
I get what I want, however, the Pdf version has the following warning printed on page
#### # maps v3.1: updated 'world': all lakes moved to separate new ### # 'lakes' database. Type '?world' or 'news(package="maps")'. #
I use suppressWarnings, but the warning is still printed. How can I hide this when I knit the document with knitr?
I would like to display the polygon of Canada on a leaflet map.
# create map
library(leaflet)
m = leaflet() %>% addTiles()
m
I was able to find the polygon for Canada: http://www.gadm.org/country.
I chose the SpatialPolygonsDataFrame format for R, but there are other formats available (such as Shapefile)
# load object in R
load("country_polygons/CAN_adm0.RData")
pol_can <- gadm
How can I display the shape on the map? I assume I have to leverage the sp package but I could not figure out how to do so.
Many thanks in advance for your help!
You can pass a SpatialPolygons* object to the addPolygons function as per Section 2.2 of the docs here.
For example (note that the following includes a ~11.4 MB download):
library(sp)
download.file('http://biogeo.ucdavis.edu/data/gadm2/R/CAN_adm0.RData', f <- tempfile())
load(f)
leaflet() %>% addTiles() %>% addPolygons(data=gadm, weight=2)
Note that GADM data can also be downloaded with the getData function in the raster package:
library(raster)
can <- getData('GADM', country='VAT', level=0)
EDIT
In response to the comments, I really like the lightweight polygon datasets that Natural Earth provides. Here's an example where I download the 1:50,000,000 countries shapefile (Admin 0) from Natural Earth, subset it to the current members of the Commonwealth of Nations, and plot those. The zipped shapefile is under 1 MB.
library(rgdal)
library(leaflet)
download.file(file.path('http://www.naturalearthdata.com/http/',
'www.naturalearthdata.com/download/50m/cultural',
'ne_50m_admin_0_countries.zip'),
f <- tempfile())
unzip(f, exdir=tempdir())
world <- readOGR(tempdir(), 'ne_50m_admin_0_countries', encoding='UTF-8')
commonwealth <- c("Antigua and Barb.", "Australia", "Bahamas", "Bangladesh",
"Barbados", "Belize", "Botswana", "Brunei", "Cameroon", "Canada", "Cyprus",
"Dominica", "Fiji", "Ghana", "Grenada", "Guyana", "India", "Jamaica", "Kenya",
"Kiribati", "Lesotho", "Malawi", "Malaysia", "Maldives", "Malta", "Mauritius",
"Mozambique", "Namibia", "Nauru", "New Zealand", "Nigeria", "Pakistan", "Papua
New Guinea", "Rwanda", "St. Kitts and Nevis", "Saint Lucia", "St. Vin. and
Gren.", "Samoa", "Seychelles", "Sierra Leone", "Singapore", "Solomon Is.",
"South Africa", "Sri Lanka", "Swaziland", "Tanzania", "Tonga", "Trinidad and
Tobago", "Tuvalu", "Uganda", "United Kingdom", "Vanuatu", "Zamibia")
leaflet() %>% addTiles() %>%
addPolygons(data=subset(world, name %in% commonwealth), weight=2)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I would like to get longitude/latitude data for the cities in my dataframe and add as 2 columns in my frame. I'm new to R and I do not know how to do it.
Could someone help me on this
My frame:
> data <- read.xlsx("example_city.xlsx", 1)
> data
City Country
1 Stockholm Sweden
2 Oslo Norway
3 Rome Italy
4 Rome Italy
5 Stockholm Sweden
6 Stockholm Sweden
7 Paris France
8 Paris France
9 Hamburg Germany
10 Paris France
11 Paris France
With reference to your original question https://stackoverflow.com/questions/20936263/use-ggplot2-to-plot-cities-on-a-map
# data
cities <- sort(c(rep('Stockholm', 3), 'Oslo', 'Rome', 'Rome', 'Paris', rep('Bonn',10), 'Paris', 'Paris', 'Stockholm'))
# get frequencies
freq <- as.data.frame(table(cities))
library(plotrix)
freq$Freq <- rescale(freq$Freq, c(1,10)) # c(scale_min, scale_max)
# get cities latitude/longitude - kindly provided by google:
library(ggmap)
lonlat <- geocode(unique(cities))
cities <- cbind(freq, lonlat)
# get matches between names {maps} names and EU country names
library(maps)
eu <- c("Austria", "Belgium", "Bulgaria", "Croatia", "Cyprus", "Czech Republic",
"Denmark", "Estonia", "Finland", "France", "Germany", "Greece",
"Hungary", "Ireland", "Italy", "Latvia", "Lithuania", "Luxembourg",
"Malta", "Netherlands", "Poland", "Portugal", "Romania", "Slovakia",
"Slovenia", "Spain", "Sweden", "United Kingdom")
warning("No matches in database for ", paste(setdiff(eu, map_data('world')$region), collapse=", "))
europe <- map_data('world', region=eu)
# plot
library(ggplot2)
ggplot(europe, aes(x=long, y=lat, group=group)) +
geom_polygon(fill="white", colour="black") +
xlim(-20, 40) + ylim(25,75) +
geom_point(data=cities, inherit.aes=F, aes(x=lon, y=lat, size=Freq), colour="red", alpha=.8) +
geom_text(data=cities, inherit.aes=F, aes(x=lon, y=lat, label=cities), vjust=1, colour="red", alpha=.5)