0

I am trying to create two versions of the world map with one data table. The columns of the data table are: Country Name iso3 FormDate The FormDate variable is a date - in this case, the date the country was officially formed. (as seen here - http://en.wikipedia.org/wiki/List_of_sovereign_states_by_date_of_formation)

formdate <- read.table(text="
ISO3\tCountry\tFormation Date
DZA\tAlgeria\t07-03-1962
AGO\tAngola\t11-11-1975
BWA\tBotswana\t09-30-1966
CMR\tCameroon\t01-01-1960
BGD\tBangladesh\t03-26-1971
IND\tIndia\t08-15-1947
ISR\tIsrael\t05-14-1948
LOS\tLaos\t10-22-1953
MYS\tMalaysia\t09-16-1963
SGP\tSingapore\t08-09-1965"
,sep="\t",header=TRUE)

> formdate
   ISO3    Country Formation.Date
1   DZA    Algeria     07-03-1962
2   AGO     Angola     11-11-1975
3   BWA   Botswana     09-30-1966
4   CMR   Cameroon     01-01-1960
5   BGD Bangladesh     03-26-1971
6   IND      India     08-15-1947
7   ISR     Israel     05-14-1948
8   LOS       Laos     10-22-1953
9   MYS   Malaysia     09-16-1963
10  SGP  Singapore     08-09-1965

The maps I would like to create are:

1: a summary map with each country color-coded by its year of formation, binned automatically in say 5-7 categories.

2: a 3-fold facet map, with separate panels showing independent countries born by 1945, after 1945 up to 1965 and anytime after that. Trouble is that I would love to be able to change these cutoff years.

This question is related to Using [R] maps package - colouring in specific nations on a world map, RScript to create World Map with own values and How to create a world map in R with specific countries filled in?, like those I am also trying to create a map with own values.

The difference here is that I need to use a date variable, and specifically, to plot binned values of those dates.

Help and advice would be very appreciated.

Community
  • 1
  • 1
user2627717
  • 344
  • 3
  • 14
  • You need to show the code you've already attempted and provide your data (e.g., with `dput`). – Thomas Oct 21 '13 at 06:57
  • Thanks. I added a short version of the data table. I thought it would be easier on readers if I did not include code, I have nothing better than the ones in the links above. – user2627717 Oct 21 '13 at 07:18

2 Answers2

1

Probably not the most straight-forward way of doing it but here is a solution to your first point:

# First changing the class of the two columns we're going to use:
formdate$Formation.Date<-as.Date(formdate$Formation.Date, "%m-%d-%Y")
formdate$ISO3<-as.character(formdate$ISO3)
formdate$ISO3[8]<-"LAO" #Laos'ISO3 code is "LAO" and not "LOS" in the wrld_simpl data
# Make regular temporal interval
intval <- cut(formdate$Formation.Date, 
              breaks = seq(min(formdate$Formation.Date),max(formdate$Formation.Date),length=5), 
              right=TRUE, include.lowest=TRUE) # So that the intervals include the lowest date and the highest
# Make these values correspond with their polygons
library(maptools)
data(wrld_simpl)
f <- rep(NA,nrow(wrld_simpl@data))
f[sapply(formdate$ISO3,function(x)which(wrld_simpl$ISO3==x))] <- intval
# Plot
plot(wrld_simpl, col=(1:6)[f])

For your second point:

#This time you can define your breakpoints before hand (don't forget to include a minimum age and a maximum age)
d <- c("1900/01/01","1945/01/01","1965/01/01","2020/01/01")
intval <- cut(formdate$Formation.Date, 
                  breaks = as.Date(d))
f <- rep(0,nrow(wrld_simpl@data))
f[sapply(formdate$ISO3,function(x)which(wrld_simpl$ISO3==x))] <- intval

and then the plotting:

par(mfcol=c(3,1)) #Here, three vertical panels
for(i in 1:3){
   par(mar=c(0,0,0,0))
   plot(wrld_simpl) #First plot the whole world
   if(any(f==i)){
       plot(wrld_simpl[f==i,],add=TRUE,col="red") #Then the countries that belong to the proper category
       }
   }
plannapus
  • 18,529
  • 4
  • 72
  • 94
1

Here's a solution using rworldmap.

library(rworldmap)

#Your data
formdate <- read.table(text="
ISO3\tCountry\tFormation Date
DZA\tAlgeria\t07-03-1962
AGO\tAngola\t11-11-1975
BWA\tBotswana\t09-30-1966
CMR\tCameroon\t01-01-1960
BGD\tBangladesh\t03-26-1971
IND\tIndia\t08-15-1947
ISR\tIsrael\t05-14-1948
LOS\tLaos\t10-22-1953
MYS\tMalaysia\t09-16-1963
SGP\tSingapore\t08-09-1965"
,sep="\t",header=TRUE)

#just using year as a first step
formdate$Formation.Year<-year(formdate$Formation.Date)

#sPDF <- joinCountryData2Map( formdate, joinCode="ISO3", nameJoinColumn="ISO3")
#joining by country name works better because of incorrect ISO3 code for Laos in the data
sPDF <- joinCountryData2Map( formdate, joinCode="NAME", nameJoinColumn="Country")

#Using defaults, change catMethod, numCats & colourPalette to change map appearance
mapCountryData(sPDF, nameColumnToPlot="Formation.Year")

... and for the 2nd bit to produce 3 panels with maps for different years :

#I've used these breaks that work with your sample data, 
#simply cahnge to work with full dataset
yearBreak1 <- 1960
yearBreak2 <- 1970

oldPar <- par(mar=c(0.7, 0, 0, 0)) #set margins for subplots top,bottom,left,right
#use layout to set up 3 panels
nPanels <- layout( cbind(c(0,1:3))
                   , heights=c(lcm(0.5),c(1,1,1))
                   , respect=F )

#add a constant column to allow plotting all countries the same colour 
formdate$constant <- 1

#subet data by yearBreaks
dF1 <- formdate[ formdate$Formation.Year <= yearBreak1, ]  
dF2 <- formdate[ formdate$Formation.Year > yearBreak1 & formdate$Formation.Year <= yearBreak2, ]                          
dF3 <- formdate[ formdate$Formation.Year > yearBreak2, ]                          

#join to a map
sPDF1 <- joinCountryData2Map( dF1, joinCode="NAME", nameJoinColumn="Country")
sPDF2 <- joinCountryData2Map( dF2, joinCode="NAME", nameJoinColumn="Country")
sPDF3 <- joinCountryData2Map( dF3, joinCode="NAME", nameJoinColumn="Country")

#plot & add titles
mapCountryData(sPDF1, nameColumnToPlot="constant", catMethod='categorical', addLegend=FALSE, mapTitle="" )
mtext(paste("<=",yearBreak1))
mapCountryData(sPDF2, nameColumnToPlot="constant", catMethod='categorical', addLegend=FALSE, mapTitle="" )
mtext(paste(">",yearBreak1,"& <=",yearBreak1))
mapCountryData(sPDF3, nameColumnToPlot="constant", catMethod='categorical', addLegend=FALSE, mapTitle="" )     
mtext(paste(">",yearBreak2))

Should produce this : rworldmap plot

Andy
  • 1,821
  • 13
  • 23
  • 1
    +1 Nice solution. Out of curiosity, what is the reason behind your peculiar `layout` call? Why creating a column of fixed-size empty panels on the left instead of adding a left margin in your call to `par(mar=...)`? – plannapus Oct 21 '13 at 15:06
  • 2
    Thanks plannapus! You were right to spot the peculiar layout call, the explanation (rather poor!) is that I've got into the habit of using layout for when I want more control, and then for simpler cases like this I take some stuff out. Just before I submitted I realised that your par command would do just as well in this case. – Andy Oct 21 '13 at 15:50
  • Ok it makes sense :) At least that wasn't lost: you made me discover argument `respect` and function `lcm`. – plannapus Oct 22 '13 at 07:01