I'm preparing a map that includes the states in the southwestern US and the northern states of Mexico. The output map of the Mexican states are rendered with many extraneous lines. How can this be fixed? My source code and resultant output image is below:
data usmx_map;
set mapsgfk.us_states (where=((statecode='CA'
or statecode='AZ' or statecode='NV' or statecode='UT' or statecode='NM' or statecode='CO' or statecode='TX')and density<=3))
mapsgfk.mexico (where=((id1='MX-02' or id1='MX-03' or id1='MX-08' or id1='MX-26' or id1='MX-05') and density <=3));
run;
proc gproject data=usmx_map out=usmx_map latlong eastlong degrees dupok;
id statecode;
run;
proc gmap map=usmx_map data=usmx_map;
id statecode;
pattern1 value=empty;
choro segment / levels=1 nolegend coutline=gray88;
run;
quit;
Thanks for any advice,
Gene
The tips from ballardw are correct.
The problem stems from the US map only going down to the state level, but the MX map going 1 step more granular than state. Here's a modified version of your most recent code, with some "gremove" added to remove the most-granular level of id, and produce a MX map of just the 'state' outlines.
data us_map;
length map_id $6.;
set mapsgfk.us_states (where=((statecode in('CA' 'AZ' 'NV' 'UT' 'NM' 'CO' 'TX')and density<=3)));
map_id=statecode;
data mx_map;
length map_id $6.;
set mapsgfk.mexico (where=((id1 in('MX-02' 'MX-03' 'MX-08' 'MX-26' 'MX-05') and density <=3)));
map_id=id1;
run;
proc gremove data=mx_map out=mx_map;
id id;
by map_id;
run;
data usmx_map; set us_map mx_map;
run;
proc gproject data=usmx_map out=usmx_map latlong eastlong degrees dupok;
id map_id;
run;
proc gmap map=usmx_map data=usmx_map;
id map_id;
pattern1 value=empty;
choro segment / levels=1 nolegend coutline=gray88;
run;
quit;
A starter:
Instead of code like
statecode='CA'
or statecode='AZ' or statecode='NV' or statecode='UT' or statecode='NM' or statecode='CO' or statecode='TX'
you use the IN operator to test if a variable value is a list of values:
statecode in ('CA' 'AZ' 'NV' 'UT' 'NM' 'CO' 'TX')
That will make code much shorter and easier to follow and maintain.
Strongly suggest not using the same data set name as the input output data set when manipulating data.
But the random lines are not random, they come from polygons connecting incorrectly. I don't use the Mexico data so I'm not sure what the difference is between Id1 and Id but since Id1 is apparently a "parent" of the values in Id I think this is similar to the problem you get when you select counties and plot by states:
proc gmap map=mapsgfk.us_counties data=mapsgfk.us_counties; where statecode in ('AZ' 'CA' 'NM' 'TX' 'NV' 'UT') and density<3; id statecode; pattern1 value=empty; choro segment / levels=1 nolegend coutline=gray88; run; quit;
Which is that the county order is not aligned with the statecode for plotting so to display the states above without random lines use a different id variable
proc gmap map=mapsgfk.us_counties data=mapsgfk.us_counties; where statecode in ('AZ' 'CA' 'NM' 'TX' 'NV' 'UT') and density<3; id id; pattern1 value=empty; choro segment / levels=1 nolegend coutline=gray88; run; quit;
This gets rid of the random lines but you need more work to remove the smaller area boundaries in Mexico.
data usmx_map; set mapsgfk.us_states (where=(statecode in ('AZ' 'CA' 'NM' 'TX' 'NV' 'UT' 'CO') and density<=3)) mapsgfk.mexico (where=(id1 in ('MX-02' 'MX-03' 'MX-08' 'MX-26' 'MX-05') and density<=3 )); run; proc gproject data=usmx_map out=usmx_map_tograph latlong eastlong degrees dupok; id statecode; run; proc gmap map=usmx_map_tograph data=usmx_map_tograph; id id; pattern1 value=empty; choro segment / levels=1 nolegend coutline=gray88; run; quit;
Gremove could be used to clean up the Mexico data but should probably be done separately before combining with US data unless you want the smaller area boundaries in the Mexico data.
Thanks for the tips and suggestions. I implemented them in the code below but the result is unchanged--or nearly so, as some of the exdtraneous lines have disappeared but most remain.
Thanks again,
Gene
data usmx_map_in;
length map_id $6.;
set mapsgfk.us_states (where=((statecode in('CA' 'AZ' 'NV' 'UT' 'NM' 'CO' 'TX')and density<=3)))
mapsgfk.mexico (where=((id1 in('MX-02' 'MX-03' 'MX-08' 'MX-26' 'MX-05') and density <=3)));
map_id=coalescec(statecode,id1);
run;
proc gproject data=usmx_map_in out=usmx_map_out latlong eastlong degrees dupok;
id map_id;
run;
proc gmap map=usmx_map_out data=usmx_map_out;
id map_id;
pattern1 value=empty;
choro segment / levels=1 nolegend coutline=gray88;
run;
quit;
The tips from ballardw are correct.
The problem stems from the US map only going down to the state level, but the MX map going 1 step more granular than state. Here's a modified version of your most recent code, with some "gremove" added to remove the most-granular level of id, and produce a MX map of just the 'state' outlines.
data us_map;
length map_id $6.;
set mapsgfk.us_states (where=((statecode in('CA' 'AZ' 'NV' 'UT' 'NM' 'CO' 'TX')and density<=3)));
map_id=statecode;
data mx_map;
length map_id $6.;
set mapsgfk.mexico (where=((id1 in('MX-02' 'MX-03' 'MX-08' 'MX-26' 'MX-05') and density <=3)));
map_id=id1;
run;
proc gremove data=mx_map out=mx_map;
id id;
by map_id;
run;
data usmx_map; set us_map mx_map;
run;
proc gproject data=usmx_map out=usmx_map latlong eastlong degrees dupok;
id map_id;
run;
proc gmap map=usmx_map data=usmx_map;
id map_id;
pattern1 value=empty;
choro segment / levels=1 nolegend coutline=gray88;
run;
quit;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.
Ready to level-up your skills? Choose your own adventure.