% -*- mode: noweb; noweb-default-code-mode: R-mode; -*- \documentclass[a4paper]{article} \title{rworldmap FAQ} \author{Andy South\footnote{Centre for Environment, Fisheries and Aquaculture Science (Cefas), Lowestoft, NR33 OHT, UK. {\tt southandy at gmail.com}}} %\VignetteIndexEntry{rworldmap FAQ} \SweaveOpts{echo=TRUE,print=FALSE, width=7, height=3.7, eps=FALSE} %\default width and height for figures %trying these SweaveOpts from raster to make vignette smaller - works \SweaveOpts{png=TRUE} \SweaveOpts{resolution=100} \SweaveOpts{keep.source=TRUE} \usepackage{Sweave} \usepackage{a4wide} %\usepackage{a4} %\usepackage{graphicx} \usepackage[colorlinks=true,urlcolor=blue]{hyperref} %this to ensure R code wraps onto next line <>= options(width=70) @ %this code used in setting up all figures later <>= par(mai=c(0,0,0.2,0),xaxs="i",yaxs="i") @ \begin{document} \maketitle HOW DO I ... \tableofcontents \vspace{0.5 cm} \section{find out what rworldmap is ?} rworldmap is an R package for visualising global scale data, concentrating on data referenced by country codes or gridded at half degree resolution. \url{http://cran.r-project.org/web/packages/rworldmap/index.html} \section{install {\tt rworldmap} ?} To install rworldmap from R, including other required packages : \newline %don't do this as R code here because otherwise it tries to install at compiling and can cause problems install.packages('rworldmap',dependencies=TRUE) Alternatively download from :\newline \url{http://cran.r-project.org/web/packages/rworldmap/index.html} \section{load the package into R after installation ?} Package {\tt rworldmap} must be loaded into R at the start of each session by either of the following 2 lines : <>= require(rworldmap) library(rworldmap) @ \section{access latest version of rworldmap source code ?} \url{http://code.google.com/p/rworld/downloads/list} \section{access this FAQ ?} From within R : \newline %don't do this as R code here because that opens the pdf at compiling and can cause problems vignette('rworldmapFAQ')\newline From the web :\newline \url{http://cran.r-project.org/web/packages/rworldmap/rworldmapFAQ.pdf} \section{map my own country level data ?} To map your own data you will need it in columns with one row per country, one column containing country identifiers, and other columns containing your data. The mapping process then involves 3 steps (or 2 if your data are already in an R dataframe). \begin{enumerate} \item read data into R \item join data to a map ( using {\tt joinCountryData2Map()} ) \item display the map ( using {\tt mapCountryData()} ) \end{enumerate} There is an example dataset within the package that can be accessed using the data command, and the command below shows how to display a subset of the rows and columns. <>= data(countryExData) countryExData[5:10,1:5] @ \subsection{Reading data into R} To read in your own data from a space or comma delimited text file you will need to use : {\tt read.csv(filename.csv)} or {\tt read.txt(filename.txt)}, type {\tt ?read.table} from the R console to get help on this. \subsection{Joining data to a country map} To join the data to a map use {\tt joinCountryData2Map}, and you will need to specify the name of column containing your country identifiers (nameJoinColumn) and the type of code used (joinCode) e.g. "ISO3" for ISO 3 letter codes or "UN" for numeric country codes. If you only have country names rather than codes use joinCode="NAME", you can expect more mismatches because there is greater variation in what a single country may be named. <>= data(countryExData) sPDF <- joinCountryData2Map( countryExData, , joinCode = "ISO3" , nameJoinColumn = "ISO3V10" ) @ \vspace{0.5 cm} You can see that a summary of how many countries are successfully joined is output to the console. You can specify verbose=TRUE to get a full list of countries. The object returned (named sPDF in this case) is of type {\tt SpatialPolygonsDataFrame} from the package {\tt sp}. This object is required for the next step, displaying the map. \subsection{Displaying a countries map} {\tt mapCountryData} requires as a minimum a {\tt SpatialPolygonsDataFrame} object and a specification of the name of the column containing the data to plot. The first line starting par ... below and in subsequent plots simply ensures the plot fills the available space on the page. \begin{center} <>= <> mapCountryData( sPDF, nameColumnToPlot="BIODIVERSITY" ) @ \end{center} In this small map the default legend is rather large. This could be fixed by calling the addMapLegend function as in the code below. <>= mapParams <- mapCountryData( sPDF , nameColumnToPlot="BIODIVERSITY" , addLegend=FALSE ) do.call( addMapLegend, c(mapParams, legendWidth=0.5, legendMar = 2)) @ Using {\tt do.call} allows the output from mapCountryData to be used in addMapLegend to ensure the legend matches the map while also allowing easy modification of extra parameters such as {\tt legendWidth}. \section{map my own half degree gridded data ?} The {\tt mapGriddedData} function can accept either \begin{enumerate} \item an object of type {\tt SpatialGridDataFrame}, as defined in the package {\tt sp} \item the name of an ESRI gridAscii file as a character string \end{enumerate} rworldmap contains an example SpatialGridDataFrame that can be accessed and printed as shown in the code below. \begin{center} <>= <> data(gridExData) mapGriddedData(gridExData) @ \end{center} \section{aggregate half degree gridded data to countries ?} mapHalfDegreeGridToCountries() takes a gridded input file, and aggregates, to a country level and plots the map, it accepts most of the same arguments as {\tt mapCountryData()}. In the example below the trick from above of modifying the legend using addMapLegend() is repeated. \begin{center} <>= <> mapParams <- mapHalfDegreeGridToCountries(gridExData, addLegend=FALSE) do.call( addMapLegend, c(mapParams, legendWidth=0.5, legendMar = 2)) @ \end{center} \section{aggregate country level data to global regions ?} Country level data can be aggregated to global regions specified by {\tt regionType} in {\tt country2Region} which outputs as text, and {\tt mapByRegion} which produces a map plot. The regional classifications available include SRES, GEO3, Stern and GBD. <>= #Using country2Region to calculate mean Environmental Health index in Stern regions. sternEnvHealth <- country2Region( inFile=countryExData , nameDataColumn="ENVHEALTH" , joinCode="ISO3" , nameJoinColumn="ISO3V10" , regionType="Stern" , FUN="mean" ) print(sternEnvHealth) @ \begin{center} <>= <> mapByRegion( countryExData , nameDataColumn="CLIMATE" , joinCode="ISO3" , nameJoinColumn="ISO3V10" , regionType="Stern" , FUN="mean" ) @ \end{center} \section{alter the appearance of my maps ?} The following arguments can be specified to alter the appearance of your plots. \begin{itemize} \item {\tt catMethod} method for categorisation of data "pretty", "fixedWidth", "diverging", "logFixedWidth", "quantiles", "categorical", or a numeric vector defining breaks. \item {\tt numCats} number of categories to classify the data into, may be modified if that exact number is not possible for the chosen catMethod. \item{\tt colourPalette} a string describing the colour palette to use, choice of : \begin{enumerate} \item "palette" for the current palette \item a vector of valid colours, e.g. c("red","white","blue") or output from RColourBrewer \item one of "heat", "diverging", "white2Black", "black2White", "topo", "rainbow", "terrain", "negpos8", "negpos9" \end{enumerate} \item {\tt addLegend} set to TRUE for a default legend, if set to FALSE the function addMapLegend() or addMapLegendBoxes() can be used to create a more flexible legend. \item {\tt mapRegion} a region to zoom in on, can be set to a country name from getMap()\$NAME or one of "eurasia","africa","latin america","uk","oceania","asia" \end{itemize} \section{create my own colour palette ?} \begin{center} <>= <> #joining the data to a map sPDF <- joinCountryData2Map( countryExData , joinCode = "ISO3" , nameJoinColumn = "ISO3V10" ) #creating a user defined colour palette op <- palette(c('green','yellow','orange','red')) #find quartile breaks cutVector <- quantile(sPDF@data[["BIODIVERSITY"]],na.rm=TRUE) #classify the data to a factor sPDF@data[["BIOcategories"]] <- cut( sPDF@data[["BIODIVERSITY"]] , cutVector , include.lowest=TRUE ) #rename the categories levels(sPDF@data[["BIOcategories"]]) <- c('low', 'med', 'high', 'vhigh') #mapping mapCountryData( sPDF , nameColumnToPlot='BIOcategories' , catMethod='categorical' , mapTitle='Biodiversity categories' , colourPalette='palette' , oceanCol='lightblue' , missingCountryCol='white' ) @ \end{center} \section{zoom in on defined regions ?} You can zoom in on a map by specifying mapRegion="Eurasia" (or by specifiying xlim and ylim) and the country outlines can be changed by borderCol="black". \begin{center} <>= <> mapCountryData( sPDF , nameColumnToPlot='BIOcategories' , catMethod='categorical' , mapTitle='Biodiversity categories' , colourPalette='palette' , oceanCol='lightblue' , missingCountryCol='white' , mapRegion='Eurasia' , borderCol='black' ) @ \end{center} %\pagebreak \section{display selected countries only ?} Subset data from your Spatial Polygons Dataframe first. e.g. to display just Landlocked Developing Countries (LLDCs). \begin{center} <>= <> sPDF <- getMap() #select countries from the map sPDF <-sPDF[which(sPDF$LDC=='LDC'),] mapCountryData( sPDF , nameColumnToPlot='continent' , colourPalette='rainbow' , mapTitle='Least Developed Countries' ) @ \end{center} \section{create map bubble plots ?} The {\tt mapBubbles} function allows flexible creation of bubble plots on global maps. You can specifiy data columns that will determine the sizing and colouring of the bubbles (using {\tt nameZsize} and {\tt nameZColour} ). The function also accepts other spatialDataFrame objects or data frames as long as they contain columns specifiying the x and y coordinates. The interactive function {\tt identifyCountries} allows the user to click on bubbles and the country name and optionally an attribute variable will be printed on the map. \begin{center} <>= <> mapBubbles( dF=getMap() , nameZSize="POP_EST" , nameZColour="continent" , colourPalette='rainbow' , oceanCol='lightblue' , landCol='wheat' ) @ \end{center} \section{add extra text beneath a plot} Use {\tt mtext} with the {\tt line} argument. Making line=-1 more negative will move the text up the plot. making line= more negative will move the text up the plot \begin{center} <>= <> sPDF <- getMap() #select countries from the map sPDF <-sPDF[which(sPDF$continent=='Africa'),] mapBubbles( dF=getMap() , nameZSize="POP_EST" , nameZColour="continent" , mapTitle='Population' , addColourLegend = FALSE) mtext("Source: Andy South, The R Journal Vol. 3/1, June 2011",side=1,line=-1) @ \end{center} \section{plot other map projections} To project a map you will need the sp package using the sf package internally and use spTransform() \begin{center} <>= <> #library(rgdal) #first get countries excluding Antarctica which crashes spTransform sPDF <- getMap()[-which(getMap()$ADMIN=='Antarctica'),] #transform to robin for the Robinson projection sPDF <- spTransform(sPDF, CRS=CRS("+proj=robin +ellps=WGS84")) mapCountryData( sPDF , nameColumnToPlot="REGION" , mapTitle='Robinson Projection' , colourPalette='topo' , addLegend = FALSE) @ \end{center} \section{combine rworldmap with other packages classInt and RColorBrewer ?} Whilst rworldmap sets many defaults internally there is also an option to use other packages to have greater flexibility. In this example the package classInt is used to create the classification and RColorBrewer to specify the colours. The following page demonstrates how multiple maps can be generated in the same figure and shows a selection of different RColorBrewer palettes. \begin{center} %I'd like to put keep.source=TRUE to keep comments, but then the R code doesn't wrap %<>= <>= <> library(classInt) library(RColorBrewer) #getting example data and joining to a map data("countryExData",envir=environment(),package="rworldmap") sPDF <- joinCountryData2Map( countryExData , joinCode = "ISO3" , nameJoinColumn = "ISO3V10" , mapResolution='coarse' ) #getting class intervals using a 'jenks' classification in classInt package classInt <- classIntervals( sPDF[["EPI"]], n=5, style="jenks") catMethod = classInt[["brks"]] #getting a colour scheme from the RColorBrewer package colourPalette <- brewer.pal(5,'RdPu') #calling mapCountryData with the parameters from classInt and RColorBrewer mapParams <- mapCountryData( sPDF , nameColumnToPlot="EPI" , addLegend=FALSE , catMethod = catMethod , colourPalette=colourPalette ) do.call( addMapLegend , c( mapParams , legendLabels="all" , legendWidth=0.5 , legendIntervals="data" , legendMar = 2 )) @ \end{center} \section{ensure plots fill the panel space available?} Use par(mar=c(bottom,top,left,right)) to set margins. This returns the previous settings so you can use oldPar <- par(...) then par(oldPar) to reset. <>= oldPar <- par(mar=c(0, 0, 0, 0)) par(oldPar) @ \section{create multi-panel plots ?} using the layout() command as shown below, layout.show() indicates how the panels are arranged Beware that the colour bar legends used when addLegend=TRUE can interfere with this ordering (addLegend=FALSE or addMapLegendBoxes() are OK) Creating 2 columns 5 rows with a 0.5cm gap at the top <>= #set margins to zero for the subplots oldPar <- par(mar=c(0, 0, 0, 0)) nPanels <- layout( cbind(c(0,1,2,3,4,5),c(0,6,7,8,9,10)) , heights=c(lcm(0.5),1,1,1,1,1) , respect=F) layout.show(nPanels) par(oldPar) @ Creating 3 columns 4 rows (with a gap at the top) appropriate for showing monthly data <>= #set margins to zero for the subplots oldPar <- par(mar=c(0, 0, 0, 0)) nPanels <- layout( rbind(c(0,0,0),c(1,2,3),c(4,5,6),c(7,8,9),c(10,11,12)) , heights=c(lcm(0.5),1,1,1,1) , respect=F ) layout.show(nPanels) par(oldPar) @ \section{add lines of latitude and longitude to a map ?} For the latitude longitude projection used in most rworldmap maps the following adds respectively : 1) Equator 2) Greenwich meridian 3) Tropics of capricorn and cancer as dashed grey lines <>= abline(h=0) abline(v=0) abline(h=c(-20,20),lty=2,col='grey') @ \end{document}