Map plot incomplete when using rworldmap - r

I have some data that I'd like to plot with rworldmap. Normally this works well. But I can't figure out why it's not plotting all the data when it says it's going to. Particularly it's not plotting data for the US.
I've got some data here: https://drive.google.com/file/d/1Fp7O2TRH5Blar56SqdRdcPh8Mb1Vb0pc/view?usp=sharing
And I'm running this code:
mergedData = readRDS("sampleData.rds")
changeHeatMapPalette = c('#D7191D', '#FDAE61', '#FFFFBF', '#ABD9E9', '#2C7BB6')
mapData = joinCountryData2Map(mergedData, joinCode="ISO2", nameJoinColumn="country", mapResolution = "high")
mapCountryData(mapData, nameColumnToPlot="change", mapTitle="", catMethod = "diverging", colourPalette = changeHeatMapPalette, numCats = 90, borderCol = "grey70")
But then I'm getting this map:
Notice how the US has no data. But it's definitely in the sample data. And it's only excluding one country, which is not the US.
108 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
[1,] "GF"
143 codes from the map weren't represented in your data
Any idea what I'm doing wrong?

The problem is that you set the colourPalette and numCats parameters in a quite random fashion.
From your data we know exactly how many categories we have, and it can be counted with: length(table(mapData$change) and you need exactly that many colors (if you provide less then mapCountData will interpolate them with a warning).
Having said that, one solution of your problem is this
mapCountryData(mapData,
nameColumnToPlot="change",
mapTitle="",
catMethod = "diverging",
colourPalette = brewer.pal(library(RColorBrewer), 'RdYlBu'),
numCats = length(table(mapData$change)),
borderCol = "grey70")

Related

Displaying counts instead of "levels" using stat_density2d

My objective is to portray the locations with varying numbers of traffic conflicts in a road intersection. My data consists of all the conflicts that we observed in a given time period at an intersection coded into a .CSV file with the following fields "time of conflict", "TTC" (means Time to Collision), "Lat", "Lon" and "Conflict Type". I figured the best way to do so would be using the 'ggmap+stat_density2d' function in R. I am using the following code:
df = read.csv(filename, header = TRUE)
int.map = get_map(location = c(mean.long, mean.lat), zoom = 20, maptype = "satellite")
int.map = ggmap(int.map, extent ="device", legend = "right")'''
int.map +stat_density2d(data = new_xdf, aes(x, y, fill = ..levels.., alpha = ..levels..),
geom = "polygon")
int.map + scale_fill_gradientn(guide = "colourbar", colours = rev(brewer.pal(7,"Spectral")),
name = "Conflict Density")
The output is a very nice map Safety Heat Map that correctly portrays the conflict hotspots. My problem is that in the legends it gives the values of "levels" automatically calculated by the 'stat_density2d()' function. I tried searching for a way to display, say, the counts of all conflict points inside each level on the legend bar but to no avail.
I did find the below link that handles a similar question, but the problem with that is that it creates a new data frame (new_xdf) with much more points than in the original data. Thus, the counts determined in that program seems to be of no use to me as I want the exact number of conflict points in my original data to be displayed in the legends bar.
How to find points within contours in R?
Thanks in advance.
Edit: Link to a sample data file
https://docs.google.com/spreadsheets/d/11vc3lOhzQ-tgEiAXe-MNw2v3fsAqnadweVrvBdNyNuo/edit?usp=sharing

Run points() after plot() on a dataframe

I'm new to R and want to plot specific points over an existing plot. I'm using the swiss data frame, which I visualize through the plot(swiss) function.
After this, want to add outliers given by the Mahalanobis distance:
mu_hat <- apply(swiss, 2, mean); sigma_hat <- cov(swiss)
mahalanobis_distance <- mahalanobis(swiss, mu_hat, sigma_hat)
outliers <- swiss[names(mahalanobis_distance[mahalanobis_distance > 10]),]
points(outliers, pch = 'x', col = 'red')
but this last line has no effect, as the outlier points aren't added to the previous plot. I see that if repeat this procedure on a pair of variables, say
plot(swiss[2:3])
points(outliers[2:3], pch = 'x', col = 'red')
the red points are added to the plot.
Ask: is there any restriction to how the points() function can be used for a multivariate data frame?
Here's a solution using GGally::ggpairs. It's a little ugly as we need to modify the ggally_points function to specify the desired color scheme.
I've assumed that mu_hat = colMeans(swiss) and sigma_hat = cov(swiss).
library(dplyr)
library(GGally)
swiss %>%
bind_cols(distance = mahalanobis(swiss, colMeans(swiss), cov(swiss))) %>%
mutate(is_outlier = ifelse(distance > 10, "yes", "no")) %>%
ggpairs(columns = 1:6,
mapping = aes(color = is_outlier),
upper = list(continuous = function(data, mapping, ...) {
ggally_points(data = data, mapping = mapping) +
scale_colour_manual(values = c("black", "red"))
}),
lower = list(continuous = function(data, mapping, ...) {
ggally_points(data = data, mapping = mapping) +
scale_colour_manual(values = c("black", "red"))
}),
axisLabels = "internal")
Unfortunately this isn't possible the way you're currently doing things. When plotting a data frame R produces many plots and aligns them. What you're actually seeing there is 6 by 6 = 36 individual plots which have all been aligned to look nice.
When you use the dots command, it tells it to place the dots on the current plot. Which doesn't really make sense when you have 36 plots, at least not the way you want it to.
ggplot is a really powerful tool in R, it provides far greater combustibility. For example you could set up the dataframe to include your outliers, but have them labelled as "outlier" and place it in each plot that you have set up as facets. The more you explore it you might find there are better plots which suit your needs as well.
Plotting a dataframe in base R is a good exploratory tool. You could set up those outliers as a separate dataframe and plot it, so you can see each of the 6 by 6 plots side by side and compare. It all depends on your goal. If you're goal is to produce exactly as you've described, the ggplot2 package will help you create something more professional. As #Gregor suggested in the comments, looking up the function ggpairs from the GGally package would be a good place to start.
A quick google image search shows some funky plots akin to what you're after and then some!
Find it here

Add "rgb" legend to R leaflet heatmap

I made some interactive heatmaps using leaflet (particularly the addHeatmap() command from the leaflet.extras package) and shiny. Having created a desired map, I would like to add a legend to it.
What I am interested in is a "rgb" legend, based on density values deduced by addHeatmap() from pure long/lat coords.
What I need is something like this map - https://www.patrick-wied.at/static/heatmapjs/example-legend-tooltip.html - unfortunately I have no knowledge of JS and can't rewrite this code in terms of R/include the right fragment of JS code for my problem.
What I tried so far is the addLegend() command, which does not give the desired result, as in this case I would need to specify a variable for which the legend would be prepared. I also tried to extract the color range and assigned values from created leaflet object, however with no success.
Here's link to full data to run the reproducible example on:
https://drive.google.com/file/d/1h3jL_PU6DGTtdIWBK02Tt37R7IB2ArH9/view
And here's top 20 records:
structure(list(latitude = c(30.309522, 30.24429616, 30.30038194,
30.27752338, 30.23294081, 30.23038507,
30.34285933, 30.24962237, 30.26594744,
30.20515821, 30.22363485, 30.2759184,
30.28283226, 30.33816909, 30.26611565,
30.18835401, 30.26704789, 30.27456699,
30.19237135, 30.1925213),
longitude = c(-97.73171047, -97.77446858, -97.77885789,
-97.71919076, -97.58937812, -97.76581095,
-97.73598704, -97.72215443, -97.74144275,
-97.8782895, -97.78329845, -97.71321066,
-97.70820152, -97.82413058, -97.7327258,
-97.81606795, -97.68989589, -97.7580592,
-97.7816127, -97.73138523)),
.Names = c("latitude", "longitude"), row.names =
c(NA, 20L), class = "data.frame")
Here's an example code, which I'd like to extend by the mentioned functionality:
library(magrittr)
library(leaflet)
library(leaflet.extras)
data <- read.csv('DATA.csv')
leaflet(data) %>%
addTiles(group="OSM") %>%
addHeatmap(group="heat", lng = ~longitude, lat = ~latitude, max=.5, blur = 60)
And here is the result of that code (on whole dataset):
https://i.stack.imgur.com/6VFNC.jpg
So to sum up what I would like to do: based on such picture I would like to extract the range of the drawn colors along with values assigned to them, and draw legend using that information.
Is there something I am missing? It looks like a pretty simple issue, but I've been struggling to find a solution for past few hours.
Thanks in advance for any help!
EDIT: extended the reproducible example.
Your sample data does not have any values to it to actually map a density overlay.
You can specify the number of bins with colorBin() and then specify those bins with your pal function. You can set the bins differently depending on your needs at the data_values distributions. The help section of colorBin() is helpful in identifying the correct parameters for your needs.
bins <- c(0,1,2,3,4)
pal <- colorBin("Spectral", domain = data_value, bins = bins, na.color = "transparent")
m <-leaflet() %>%
addTiles() %>%
addHeatmap(lng= long_cords, lat = lat_cords, intensity = data_value,
blur = 20, max = 400, radius = 15, cellSize = 3) %>%
addLegend(pal = pal, values = data_value,
title="Heat map legend")
You'll have to play around with the addHeatmap arguments to get an the right transparency and density settings.

Why do colours merged onto a shapefile in base R display incorrectly?

I have a shapefile:
I would like to colour each polygon according to the value it holds. I can do this using the following code:
shapefile$colour =
ifelse(shapefile$Count >= 0 & shapefile$Count <= 40,
"blue",
"red")
However, what I would like to do is to decide on my colour scheme in a data frame and then merge this onto the shapefile:
shapefile = merge(shapefile, dataframe, by = "Polygon", all.x = TRUE)
When I do this, I do not get the colours I have specified, despite them reading correctly when I check shapefile#data.
Could anyone help me understand why this happens and also if there is any way around it? Thank you!

How to map a single US state (MO) county population data using maps package?

I'm having difficulty mapping gradient colors to some county-level population data I have using the base R package maps. I know that colors must be interpolated to the dataframe, but I'm not sure how that is then translated to the map. Here is the code I'm using:
library(dplyr)
require(maps)
my_fake_data <- data_frame(
county = sample(c('list','of','all','counties'),115,T),
county_population = sample(1:1000000,115,T))
grey_black <- colorRampPalette(c('grey50','black'))
map_data <- my_fake_data %>%
arrange(county_population) %>%
mutate(county_population_color = grey_black(nrow(.)))
map('county','missouri',interior = T,fill =T,
col = grey_black(map_data$county_population_color))
How do I tell R to map colors in the correct order? My sense tells me to attach my data to map's internal database, but I can't find the documentation to do it correctly - - or, more likely, I'm just wrong. Any help would be greatly appreciated.
To answer your question, you will need to access the county.fips data frame contained in the maps package. This will have the fips number and the state, county name. This list is in the correct order for mapping. The code example below extracts the Missouri counties and randomly colors a couple for verification:
mocounties<-county.fips[grepl('missouri', county.fips$polyname),]
mocounties$col<-"grey"
mocounties$col[5]<-"red"
mocounties$col[15]<-"green"
mocounties$col[115]<-"blue"
map('county','missouri', interior = T,fill =T,
col = mocounties$col)

Resources