%let name=mobile_os_map;
filename odsout '.';
libname here '.';

/*
This bit of tricky code downloads the csv file on-the-fly,
so you don't have to do it manually :)

How did I figure out the URL? ...
Viewed the report in Google Chrome: 
http://gs.statcounter.com/#mobile_os-ww-monthly-200812-200812-map
Right-clicked on the "Download data" link, and ran 'Inspect element'.
Right-clicked on the href line, and did a 'Copy link address'
Then pasted it into the SAS code below...
http://gs.statcounter.com/chart.php?map=1&statType_hidden=mobile_os&region_hidden=ww&granularity=monthly&statType=Mobile%20OS&region=Worldwide&fromMonthYear=2008-12&toMonthYear=2008-12&csv=1
*/

data temp_master; 
length OS $100;
run;

%macro get_data(datestr);

%let csvname=&name..csv;

%include '../data_vault/proxy.sas';
/*
I %include a file that sets the my_proxy macro variable.
You won't be able to use my proxy, therefore set your own
macro variable, which will be something like the following:
%let my_proxy=http://yourproxy.com:80;
*/

filename xlsfile url
"http://gs.statcounter.com/chart.php?map=1&statType_hidden=mobile_os&region_hidden=ww&granularity=monthly&statType=Mobile%20OS&region=Worldwide&fromMonthYear=&datestr&toMonthYear=&datestr&csv=1"
 proxy="&my_proxy";

data _null_;
 n=-1;
 infile xlsfile recfm=s nbyte=n length=len _infile_=tmp;
 input;
 file "&csvname" recfm=n;
 put tmp $varying32767. len;
run;

PROC IMPORT OUT=temp_data DATAFILE="&csvname" DBMS=CSV REPLACE;
 GETNAMES=YES;
 DATAROW=2;
 GUESSINGROWS=1000;  /* otherwise some long country names are cut short */
RUN;

data temp_data; set temp_data;
year=.; month=.;
year=substr("&datestr",1,4);
month=substr("&datestr",6,2);
run;

proc sort data=temp_data out=temp_data;
by continent year month;
run;
proc transpose data=temp_data out=temp_data (rename=(Continent=Country_name _name_=OS col1=percent));
by continent year month;
run;
proc sql;
create table temp_data as
select *
from temp_data
group by Country_name
having percent=max(percent);
quit; run;

data temp_master; set temp_master temp_data;
if Country_name^='' then output;
run;

%mend;


/*
Call the macro once for each month
Then save the results in a permant data set, so you don't have to download
the data each time you run the SAS job (comment out the calling of
the macro, and only uncomment it when you need to 'freshen' the data).
*/
%get_data(2008-12);
%get_data(2009-01);
%get_data(2009-02);
%get_data(2009-03);
%get_data(2009-04);
%get_data(2009-05);
%get_data(2009-06);
%get_data(2009-07);
%get_data(2009-08);
%get_data(2009-09);
%get_data(2009-10);
%get_data(2009-11);
%get_data(2009-12);
%get_data(2010-01);
%get_data(2010-02);
%get_data(2010-03);
%get_data(2010-04);
%get_data(2010-05);
%get_data(2010-06);
%get_data(2010-07);
%get_data(2010-08);
%get_data(2010-09);
%get_data(2010-10);
%get_data(2010-11);
%get_data(2010-12);
%get_data(2011-01);
%get_data(2011-02);
%get_data(2011-03);
%get_data(2011-04);
%get_data(2011-05);
%get_data(2011-06);
%get_data(2011-07);
%get_data(2011-08);
%get_data(2011-09);
%get_data(2011-10);
%get_data(2011-11);
%get_data(2011-12);
%get_data(2012-01);
%get_data(2012-02);
%get_data(2012-03);
%get_data(2012-04);
%get_data(2012-05);
%get_data(2012-06);
%get_data(2012-07);
%get_data(2012-08);
%get_data(2012-09);
%get_data(2012-10);
%get_data(2012-11);
%get_data(2012-12);
%get_data(2013-01);
%get_data(2013-02);
%get_data(2013-03);
%get_data(2013-04);
%get_data(2013-05);
%get_data(2013-06);
%get_data(2013-07);
%get_data(2013-08);
%get_data(2013-09);
%get_data(2013-10);

data here.&name; set temp_master;
run; 


proc format;
value monfmt
1='January'
2='February'
3='March'
4='April'
5='May'
6='June'
7='July'
8='August'
9='September'
10='October'
11='November'
12='December'
;
run;

/* this is where you can easily subset your data to 1 month, if you're experimenting... */
data my_data; set here.&name /* (where=(year=2012 and month=7)) */;
OS=trim(left(translate(OS,' ','_')));
run;

options fmtsearch=(sashelp.mapfmts);
data my_map; set maps.world (where=(density<=1 and cont^=97));

length Country_name $100;
Country_name=put(id,glcnsm.);
if Country_name='United States' then Country_name='United States of America';
if Country_name='Russia' then Country_name='Russian Federation';
if Country_name='Antigua/Barbuda' then Country_name='Antigua and Barbuda';
if Country_name='Turks/Caicos Islands' then Country_name='Turks and Caicos Islands';
if Country_name='Korea, South' then Country_name='South Korea';
if Country_name='Korea, North' then Country_name='North Korea';
if Country_name='Central African Rep.' then Country_name='Central African Republic';
if Country_name='Ivory Coast' then Country_name='Cote dIvoire';
if Country_name='Libya' then Country_name='Libyan Arab Jamahiriya ';
if Country_name='Syria' then Country_name='Syrian Arab Republic';
if Country_name='Trinidad And Tobago' then Country_name='Trinidad and Tobago';
if Country_name='Macau' then Country_name='Macao';
if Country_name='St. Lucia' then Country_name='Saint Lucia';
if Country_name='Bosnia/Herzegovina ' then Country_name='Bosnia and Herzegovina ';
if Country_name='Brunei' then Country_name='Brunei Darussalam';
if Country_name='Falkland Islands' then Country_name='Falkland Islands (Malvinas)';
if Country_name='Kyrgyzstan' then Country_name='Kyrgyz Republic';
if Country_name='Laos' then Country_name='Lao Peoples Democratic Republic';
if Country_name='Saint Kitts/Nevis' then Country_name='Saint Kitts and Nevis';
if Country_name='St. Pierre/Miquelon' then Country_name='Saint Pierre and Miquelon';
if Country_name='Saint Vincent/Grenadines' then Country_name='Saint Vincent and the Grenadines';
if Country_name='Sao Tome/Principe' then Country_name='Sao Tome and Principe';
if Country_name='Slovakia' then Country_name='Slovakia (Slovak Republic)';
if Country_name='West Bank' then Country_name='Palestinian Territory';
run;

/* Some code I used to help determine which country names needed adjusting (above) */
/*
proc sql;
create table no_match as
select unique Country_name
from my_map
where Country_name not in (select unique Country_name from my_data);
create table no_match2 as
select unique Country_name
from my_data
where Country_name not in (select unique Country_name from my_map);
quit; run;
*/

/* 
my_data doesn't contain all the countries, therefore they don't all
have hover-text with the country name.  Therefore I merge in all the
country names.
*/
proc sql;
create table all_names as
 select unique Country_name
 from my_map;
create table all_dates as
 select unique year, month
 from my_data;
create table all as
 select unique all_names.Country_name, all_dates.year, all_dates.month
 from all_names, all_dates;
create table my_data as
 select unique all.*, my_data.OS, my_data.percent
 from all left join my_data
 on all.Country_name=my_data.Country_name and all.year=my_data.year and all.month=my_data.month;
quit; run;

data my_data; set my_data;
length monthname $20;
monthname=put(month,monfmt.);
run;

proc sort data=my_data out=my_data;
by descending year descending month monthname;
run;

data my_data; set my_data;
if OS='Unknown' then OS='unknown';
if OS='' then OS='no data';
length my_html $200;
my_html=
 'title='||quote(trim(left(Country_name))||':  '||trim(left(percent))||'% '||trim(left(OS)))||
 ' href="mobile_os_map_info.htm"';
if OS='no data' then my_html=
 'title='||quote(trim(left(Country_name))||':  no data');
run;

/*
Some of the 'oddball' OS only show up in 1 small country
in 1 (or very few) months, etc -- I don't want to plot 
them in the legend, because it will just make the real
data harder to see.
*/
data my_data; set my_data;
plot_OS=OS;
if plot_OS not in (
 'Android'
 'BlackBerry OS'
 'Series 40'
 'Sony Ericsson'
 'SymbianOS'
 'iOS'
 'no data'
 )
 then plot_OS='other / unknown';
run;


goptions device=png;
goptions xpixels=1100 ypixels=600;
goptions cback=cxD8EFFF;
goptions border;
 
ODS LISTING CLOSE;
ODS HTML path=odsout body="&name..htm" 
 (title="Worldwide Mobile Operating System Popularity") 
 style=sasweb nogfootnote;

goptions gunit=pct htitle=4.0 ftitle="albany amt/bold" htext=2.5 ftext="albany amt/bold";

legend1 label=none shape=bar(.15in,.15in) position=(bottom left) mode=share
 across=1 offset=(8,15);

options nobyline;
title1 ls=1.5 "Worldwide Mobile Operating System Popularity";
title2 ls=1.0 h=3.5 "#byval(monthname), #byval(year)";

footnote1 j=r link='http://gs.statcounter.com/chart.php?map=1&statType_hidden=mobile_os&region_hidden=ww&granularity=monthly&statType=Mobile%20OS&region=Worldwide&fromMonthYear=2012-07&toMonthYear=2012-07&csv=1'
  ls=1.0 color=gray "Data Source: statcounter.com";

pattern1 v=s c=cxFFD92F; 
pattern2 v=s c=cx8DA0CB; 
pattern3 v=s c=cxFC8D62; 
pattern4 v=s c=cx66C2A5; 
pattern5 v=s c=cxE78AC3; 
pattern6 v=s c=cxA6D854; 
pattern7 v=s c=gray80; 
pattern8 v=s c=grayee; 

proc gmap data=my_data map=my_map all uniform;
format month z2.;
by year month monthname notsorted;
id Country_name;
choro plot_OS /
 midpoints=
 'Android'
 'BlackBerry OS'
 'Series 40'
 'Sony Ericsson'
 'SymbianOS'
 'iOS'
 'other / unknown'
 'no data'  /* this is an extra one, not really in the data, 
               that matches with pattern8 which I set to the
               same color as 'cdefault' ... which is the color
               countries with no data get. */
 cdefault=grayee coutline=gray50
 legend=legend1 html=my_html
 des='' name="&name";
run;

/*
title "In data, but not in map";
proc print data=no_match2; run;

title "In map, but not in data";
proc print data=no_match; run;
*/

quit;
ODS HTML CLOSE;
ODS LISTING;
