BookmarkSubscribeRSS Feed
pranav
Calcite | Level 5

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.

13 REPLIES 13
ballardw
Super User

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.

Darrell_sas
SAS Employee

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.

 

 

 

pranav
Calcite | Level 5

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.

GraphGuy
Meteorite | Level 14

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.

 

Darrell_sas
SAS Employee

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; 

 

pranav
Calcite | Level 5

 

 

 

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.

GraphGuy
Meteorite | Level 14

Try using the 'nodateline' option when you gproject.

 

pranav
Calcite | Level 5

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);

pranav
Calcite | Level 5

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

pranav
Calcite | Level 5

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

Darrell_sas
SAS Employee

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...

 

pranav
Calcite | Level 5

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.

GraphGuy
Meteorite | Level 14

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

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 13 replies
  • 5270 views
  • 1 like
  • 4 in conversation