Data visualization with SAS programming

Proc Gmap

Reply
Occasional Contributor
Posts: 7

Proc Gmap

[ Edited ]

I want to create a bubble map with the proc gmap. While i am using maps.world dataset which is having  the continent for America. I am annotating the data points and also projecting the annoated dataset with the proc gproject, but the map is coming in polygamy structure. Could you please suggest me how to get the proper map with the outline?

This is the code that i am currently using is as follows: 

 

options fmtsearch=(work, sashelp.mapfmts) nodate nonumber noerrorabend
orientation=landscape leftmargin=1in rightmargin=1in topmargin=1in bottommargin=1in;
goptions reset=all cback=white border htitle=12pt htext=10pt;


/* Creating a graph across different regions*/

data world(where=(x is not missing and y is not missing));
length country $50.;
set mapsgfk.world;
*country=put(id,glcnsm.);
country=strip(idname);
if country ='Dominican Republic' then country='Dominican Rep.';else if country ='Korea, South' then country='South Korea';else if country ='Netherlands Antilles' then country='Dutch Antilles';
else if country ='South Africa' then country='South Africa';else if country ='Trinidad And Tobago' then country='Trinidad,Tobago';else if country ='United Arab Emirates' then country='Utd.Arab Emir.';
run;

proc sql noprint;
create table world1 as
select distinct a.*,b.region,b.unit1
from world as a inner join final1 as b on a.country=b.country;
*order by b.region,a.country,b.unit1,a.x,a.y;
quit;

data world1;
set world1 /*(drop=x y)*/;
by region country unit1 ;
*if first.country;
*Here converting degrees to radiants;
x=atan(1)/45*long;
y=atan(1)/45*lat;
x=-x;
keep region country x y unit1;
run;

proc gproject data=world1 out=world1 project=gnomon dupok;
id region country ;/*remove unit1*/
run;

proc sort;
by region country unit1;
run;

data repl;
set world1;
by region country;
if first.country;
run;

data repl;
length position $8. function style color text $100.;
set repl;
flag=1;
xsys='2'; ysys='2'; hsys='3'; function='pie'; when ='a'; rotate= 360;
style='solid';
size=sqrt(unit1/3.14)*.02;
color='green';
output;
function='label';style='Albany AMT'; position='8';rotate=.; color='vibg';
size=.;text=strip(country);
output;
function='label';style=''; position='12';rotate=.;color='red';
size=.;
text=strip(put(unit1,8.));
output;
run;

/*data combined;*/
/* set world1 repl;*/
/*run;*/


%macro rpt4(region);

data world2;
set world1;
where region="&region." ;
run;

title;footnote;
ods escapechar = '^';
ods listing close;
ods pdf file="C:\Users\ppothine\Desktop\Report\f&region..pdf" ;
ods graphics on;

title3 j=r 'page 1 of 1';title4 j=c 'Summary table across different regions';
title5;
footnote2 j=r "&todaydate &todaytime";

pattern value=mempty color=blue repeat=100;
proc gmap data=world2 map=world2 ;
id region country;
choro country / discrete nolegend anno=repl(where=(region="&region."));
run;
quit;

ods _all_ close;
%mend;

%rpt4(Americas);

%rpt4(Asia Pacific);

%rpt4(EMEA);

%rpt4(Japan);

 

I am attaching an output for the america.

 

I would like to know what is the input data set for getting the  proper map.

Grand Advisor
Posts: 9,699

Re: proc gmap

Since your WORLD dataset contains ordered coordinates you do not want to sort it if you are going to use to draw a map. Proc SQL reordered your data when creating World2. So the ordered x,y coordinate pairs are not in proper drawing order.

 

I am not sure if you were attempting to merge the values needed for the bubbles to your map data set or not. If that is what you needed the merge for that is unneeded. The Gmap procedure has a map data set for coordinates and a Data data set for response options used in bubble, prism or choro. As long as the Data data set has the coordinates of the point or id values used you should be okay.

 

It may help to provide the actual proc gmap code as well.

SAS Employee
Posts: 170

Re: proc gmap

A few additional things:

1. You are taking the x,y missing values out in your first data step (world).  Missing values represent holes.  You are only taking the indicator of a hole (missing values) without taking the actual hole.  

2.  I don't know what is in 'final1', but 'mapsgfk.world' is sorted by ID.  So I wonder if the "by region country unit1" is sorted correctly.

3.  You create "combined" by adding "world1" and "rep1" to it, but you never Proc GPROJECT it.  You just do rep1.  I too would like to see your GMAP.

 

 

 

Occasional Contributor
Posts: 7

Re: proc gmap

Hello Darell,
Thanks for your response, I would like to add some information regarding the final1 dataset. It contains the continents(regions Variable) like AsiaPacific, Americas, EMEA and Japan along with the countries(Country variable) and the number of lenses(unit1 variable)that are shipped to those countries.

SAS Employee
Posts: 963

Re: Proc Gmap

Here's a document I wrote about annotating markers on a map:

 

  http://robslink.com/SAS/book2/Chapter_07_Annotating_on_Maps.pdf 

 

It would be good to read this first, and then start from the beginning, and create your map one step at a time, making sure each step is working properly and producing the desired map.

 

SAS Employee
Posts: 170

Re: Proc Gmap

[ Edited ]

I think there are alot of problems here.  You are not Proc GPROJECTing your map itself.  I just adjusted your program.

Also, you might want to place your annotate on the centroid of the country.  You are currently using the first point in the US, for example.  That is way off in Alaska.  The centroid macro is:  

%annomac;
%centroid(InputDS,OutputDS,idvar,SEGONLY=1); 

The last argument is to use the largest segment of a country only.

 

I hope you can figure out your program from the one below.

 

Here is your modified program:


data world; /*Don't delete missing values*/
length country $50.;
set mapsgfk.world;
*country=put(id,glcnsm.);
x=Long; y=lat; /*Moved unprojected to x,y*/
country=strip(idname);
if country ='Dominican Republic' then country='Dominican Rep.';else if country ='Korea, South' then country='South Korea';else if country ='Netherlands Antilles' then country='Dutch Antilles';
else if country ='South Africa' then country='South Africa';else if country ='Trinidad And Tobago' then country='Trinidad,Tobago';else if country ='United Arab Emirates' then country='Utd.Arab Emir.';
run;

data final1; 
length country $50. region $50.;
Country="China"; Unit1=10000; Region="AsiaPacific"; /*x=8.4465511368; y=46.8147705; */ output; 
Country="United States"; Unit1=100000; Region="Americas"; /*x=-99.56837548; y=37.1680595;*/ output;
run;

proc sql noprint;
create table world1 as
select distinct a.*,b.region,b.unit1 from world as a inner join final1 as b on a.country=b.country order by b.region,a.country,b.unit1,a.x,a.y;
quit;

data world1;
set world1 /*(drop=x y)*/;
by region country unit1 ;
*if first.country;
*Here converting degrees to radiants;
*x=atan(1)/45*long;  /*Not sure why radians */
*y=atan(1)/45*lat;   /* because world isn't */
*x=-x;
*keep region country x y unit1;
run;

data repl;
set world1;
by region country unit1;
if first.country;
run;

data repl;
length position $8. function style color text $100.;
set repl;
flag=1;
xsys='2'; ysys='2'; hsys='3'; function='pie'; when ='a'; rotate= 360;
style='solid';
size=sqrt(unit1/3.14)*.02;
color='green';
output;
function='label';style='Albany AMT'; position='8';rotate=.; color='vibg';
size=.;text=strip(country);
output;
function='label';style=''; position='12';rotate=.;color='red';
size=.;
text=strip(put(unit1,8.));
output;
run;

data combined;
set world repl; /*world instead of world1*/
run;

/* Used combined here.  Also eastlong and degrees */
/*
proc gproject data=combined out=combined project=gnomon  dupok eastlong degrees;
id region country;
run;
*/

/*seperated map and annotate */
data map anno; set combined;
if flag=1 then output anno;
else output map;
run;

pattern c='tan';
proc gmap data=map map=map anno=anno; id country segment; choro segment / levels=1; run; 

 

Occasional Contributor
Posts: 7

Re: Proc Gmap

[ Edited ]

 

 

 

The current problem is  in the pdf's which  is to scale the maps. In the pdf of EMEA the map is towards the left and would like to get it to center. In the Asia pacific the some part of russia is towards the left and needs to be right. The annoations on the map of Asia Pacific and EMEA are overlapping on one another. Is it possible to point out an arrow to that place and extend the line and then place the  annaoted text.

SAS Employee
Posts: 963

Re: Proc Gmap

Try using the 'nodateline' option when you gproject.

 

Occasional Contributor
Posts: 7

Re: Proc Gmap

This is the current code that gets those maps:

options nodateline leftmargin=0.5in rightmargin=0.5in topmargin=0.5in bottommargin=0.5in;
data world; /*Don't delete missing values*/
length region country $50.;
set mapsgfk.world mapsgfk.china(in=b keep =id long lat where=(id="CN-8100"));
*country=put(id,glcnsm.);
x=Long; y=lat; /*Moved unprojected to x,y*/
country=strip(idname);
region=strip(put(cont,contfmt.));
if b then do;country="Hong Kong";region="Asia Pacific";id="HK";segment=1; end;

%let SouthKorea=%nrstr("Korea, Democratic People's Republic of");
%put &SouthKorea;
if country ='Dominican Republic' then country='Dominican Rep.';else if country =&SouthKorea. then country='South Korea';
else if country ='Trinidad and Tobago' then country='Trinidad,Tobago';else if country ='Taiwan, Province of China' then country='Taiwan';else if country ='Russian Federation' then country='Russia';
else if country ='United Arab Emirates' then country='Utd.Arab Emir.'; else if country ='South Africa' then country='South Africa';

if region='Europe' then region='EMEA';
else if region='Asia' then region='Asia Pacific';
else if region='Oceania' then region='Asia Pacific';
else if region='Africa' then region='EMEA';
else if region in ('North America','South America') then region='Americas';

*As per Jose Ochoa suggestion;
if country='Japan' then region='Asia Pacific';
else if country in ('Utd.Arab Emir.','Russia','Israel') then region='EMEA';
else if country='Bonaire, Saint Eustatius and Saba' then region='Americas';

ord=_n_;
run;

data final_;
set final1;
*As per Jose Ochoa suggestion;
if country='Dutch Antilles' then country='Bonaire, Saint Eustatius and Saba';
if country='Bermuda' then region='Americas';else if country='Japan' then region='Asia Pacific';
else if country='Australia' then region='Asia Pacific';
else if country='Utd.Arab Emir.' then region='EMEA';
run;

proc sql noprint;
create table world1 as
select distinct a.*,b.unit1 from world as a left join final_ as b on a.region=b.region and a.country=b.country order by a.region,a.country,a.segment,b.unit1;
quit;

proc sort;
by region country id segment unit1;
run;

%annomac;
%centroid(world1,repl,region country id segment unit1,SEGONLY=1);

proc sql feedback undo_policy=none noprint;
create table repl as
select distinct a.*,b.ord from repl as a natural join (select distinct region,country,ord from world1) as b order by a.region,a.country,b.ord;
quit;

%macro region(region);
data repl_(where=(region="&region."));
set repl(where=(region="&region." and unit1 ne . )) ;
by region country ord;
if first.country;
run;

proc sort;
by ord;
run;

data repl_;
length position $8. function style color text $100.;
set repl_;
flag=1;
xsys='2'; ysys='2'; hsys='3'; function='pie'; when ='a'; rotate= 360;
style='solid';
size=sqrt(unit1/3.14)*.008;
%if &region=EMEA or &region=Japan %then %do;size=sqrt(unit1/3.14)*.002;%end;
color='light green';position='1';
output;

function='label';style='Albany AMT'; position='4';color='CXFF00FF';
text=strip(id); size=1;
output;

position='8';color='blue';
text=strip(put(unit1,8.)); size=1;
output;
run;

proc sort data=world1 out=world2;
by ord;
where region="&region.";
run;

title;footnote;
ods listing close;ods graphics on;
ods pdf file="C:\Users\ppothine\Desktop\Report\f&region..pdf" ;
title3 j=r 'page 1 of 1';title4 j=c "Graphical Representation for &region.";title5;
footnote2 j=r "&sysdate. &systime.";

pattern c='white';
proc gmap data=world2 map=world2 anno=repl_;
id region id segment;
choro unit1 / levels=1 stat=first nolegend;
run;
quit;
ods _all_ close;
%mend;

%region(Americas);

%region(Asia Pacific);

%region(EMEA);

Occasional Contributor
Posts: 7

Re: Proc Gmap

Can you check the post above. I just updated it.

Occasional Contributor
Posts: 7

Re: Proc Gmap

Need some information on projecting and how to  scale the maps so that they good to see.

SAS Employee
Posts: 170

Re: Proc Gmap

[ Edited ]

NODATELINE goes in GPROJECT.  Proc GPROJECT data=... OUT=... PROJECT=none NODATELINE;

It is because Russia and some other countries go from 180 to -180 longitude which is the default way of projecting the world.

I did not see a GPROJECT in your code at all.

 

Here is the doc to GPROJECT:

http://support.sas.com/documentation/cdl/en/graphref/67881/HTML/default/viewer.htm#n0h81palrr0ucqn11...

 

Occasional Contributor
Posts: 7

Re: Proc Gmap

Here is the following code with the proc gproject in it.

 

options leftmargin=0.5in rightmargin=0.5in topmargin=0.5in bottommargin=0.5in;
data world; /*Don't delete missing values*/
length region country $50.;
set mapsgfk.world mapsgfk.china(in=b keep =id long lat where=(id="CN-8100"));
*country=put(id,glcnsm.);
x=Long; y=lat; /*Moved unprojected to x,y*/
country=strip(idname);
region=strip(put(cont,contfmt.));
if b then do;country="Hong Kong";region="Asia Pacific";id="HK";segment=1; end;

%let SouthKorea=%nrstr("Korea, Democratic People's Republic of");
%put &SouthKorea;
if country ='Dominican Republic' then country='Dominican Rep.';else if country =&SouthKorea. then country='South Korea';
else if country ='Trinidad and Tobago' then country='Trinidad,Tobago';else if country ='Taiwan, Province of China' then country='Taiwan';else if country ='Russian Federation' then country='Russia';
else if country ='United Arab Emirates' then country='Utd.Arab Emir.'; else if country ='South Africa' then country='South Africa';

if region in ('Europe','Africa') then region='EMEA';
else if region in ('Asia','Oceania') then region='Asia Pacific';
else if region in ('North America','South America') then region='Americas';


if country='Japan' then region='Asia Pacific';
else if country in ('Utd.Arab Emir.','Russia','Israel','Saudi Arabia','Yemen','Oman') then region='EMEA';
else if country='Bonaire, Saint Eustatius and Saba' then region='Americas';

ord=_n_;
run;

data final_;
set final1;

if country='Dutch Antilles' then country='Bonaire, Saint Eustatius and Saba';
if country='Bermuda' then region='Americas';else if country='Japan' then region='Asia Pacific';
else if country='Australia' then region='Asia Pacific';
else if country='Utd.Arab Emir.' then region='EMEA';
run;

proc sql noprint;
create table world1 as
select distinct a.*,b.unit1 from world as a left join final_ as b on a.region=b.region and a.country=b.country order by a.ord,a.region,a.country,a.segment,b.unit1;
quit;

proc gproject data=world1 out=world1 nodateline project=none;
id region country id;
run;

proc sort;
by region country id segment unit1;
run;
%annomac;
%centroid(world1,repl,region country id segment unit1,SEGONLY=1);

proc sql feedback undo_policy=none noprint;
create table repl as
select distinct a.*,b.ord from repl as a natural join (select distinct region,country,ord from world1) as b order by a.region,a.country,b.ord;
quit;

%macro region(region);
data repl_(where=(region="&region."));
set repl(where=(region="&region." and unit1 ne . )) ;
by region country ord;
if last.country;
run;

proc sort;
by ord;
run;

data repl_;
length position $8. function style color text $100.;
set repl_;
flag=1;
xsys='2'; ysys='2'; hsys='3'; function='pie'; when ='a'; rotate= 360;
style='solid';
size=sqrt(unit1/3.14)*.008;
%if &region=EMEA or &region=Japan %then %do;size=sqrt(unit1/3.14)*.002;%end;
color='light green';position='1';
output;

function='label';style='Albany AMT'; position='4';color='CXFF00FF';
text=strip(id); size=1;
output;

position='8';color='blue';
text=strip(put(unit1,8.)); size=1;
output;
run;

proc sort data=world1 out=world2;
by ord;
where region="&region.";
run;

title;footnote;
ods listing close;ods graphics on;
ods pdf file="C:\Users\ppothine\Desktop\Report\f&region..pdf" ;
title3 j=r 'page 1 of 1';title4 j=c "Graphical Representation for &region.";title5;
footnote2 j=r "&sysdate. &systime.";

pattern c='white';
proc gmap data=world2 map=world2 anno=repl_;
id region id segment;
choro unit1 / levels=1 stat=first nolegend;
run;
quit;
ods _all_ close;
%mend;

%region(Americas);

%region(Asia Pacific);

%region(EMEA);

 

I tried with the proc gproject in the above code but still the output remains the same as before. Could you please guide me? Thanks in advance.

SAS Employee
Posts: 963

Re: Proc Gmap

You've got a lot of code, and I'm not sure it's doing what you think it's doing.

I would recommend starting small/simple, and working your way up to the final map you want.

That way, you can understand each piece of code, and know that it is having the desired effect.

 

Here is a small/simple example I would recommend starting with...

 

title "Default projection";
proc gmap data=mapsgfk.world map=mapsgfk.world (where=(cont not in (92 97 91 93 94)));
id id;
choro cont / discrete;
run;

 

proc gproject data=mapsgfk.world (where=(cont not in (92 97 91 93 94))) out=newmap
latlong degrees eastlong nodateline;
id id;
run;

 

title "Custom projection, using nodateline";
proc gmap data=newmap map=newmap;
id id;
choro cont / discrete;
run;

 

 

gmap10.png

 

gmap11.png

 

Post a Question
Discussion Stats
  • 13 replies
  • 446 views
  • 1 like
  • 4 in conversation