BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Indescribled
Obsidian | Level 7

I am trying to take the Tidy Tuesday data for this week and turn it into a choropleth map of the US.

 

I think everything works correctly up until PROC SGMAP at which time I get this error: ERROR: Variable FIPS not found

 

I checked via PROC PRINT to make sure fips is there, and it seems to be, so I am unsure of what to do next. 

 

* Get data 1;
filename test1234 url "https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-10-05/nurses.csv";

proc import out=nurses datafile=test1234 dbms=csv replace; 
	guessingrows = max; 
run;

* Filter to 2020 only;
data nurses;
	set nurses;
	where Year = 2020;
run;

* Solution here to get FIPS data with state name
https://communities.sas.com/t5/SAS-Programming/Convert-Full-State-Name-to-Abbreviation/td-p/738723;

data fips;
  fmtname='$FIPS';
  length fips 8 label $2 start $20 ;
  do fips=1 to 95;
    start=fipnamel(fips);
    if start ne 'Invalid Code' then do;
       label=fipstate(fips);
       output;
    end;
  end;
run;

proc format cntlin=fips ; run;

data test;
 set fips;
 statecode=put(start,$fips.);
run;

* Merge nurses data with fips data;
proc sql;
	create table work.nurse_fips as
	select t1.State,
		   t1.'Total Employed RN'n,
		   t2.fips,
		   t2.start
	from nurses t1
		left join work.fips t2 on (t1.State = t2.start);
quit;

* Confirming output to make sure fips column exists due to error;
proc print 
	data=work.nurse_fips;
run;

* Plot template
* https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/grmapref/n01dh0rm86m35un12p8j7dz9ugog.htm;

data states;
  set maps.states;
  if state ^in(2,15,72);
  x = -x * 45/atan(1); 
  y =  y * 45/atan(1);
run;

data plot_data; 
set maps.uscenter;
  if state ^in(2,15,72) and ocean^='Y';
  long = -long;
  statename = fipstate(state);
run;

* New error is: "ERROR: Variable FIPS not found";
proc sgmap mapdata=states
  maprespdata=work.nurse_fips
  plotdata=plot_data;

  esrimap
  url='http://services.arcgisonline.com/arcgis/rest/services/
Canvas/World_Light_Gray_Base';

  choromap 'Total Employed RN'n / mapid=fips density=2
    name='choro';

  text x=long y=lat text=statename /
    textattrs=(size=6pt);

  gradlegend 'choro' / title='Total Employed RN, 2020' 
	   extractscale;

run;

quit;

 

1 ACCEPTED SOLUTION

Accepted Solutions
Indescribled
Obsidian | Level 7

After a lot of trial and error I managed to get it to work. Here is the full working code and explanation if anyone else runs across this in the future:

 

The issue I seemed to be having was that choromap mapid=??? NEEDS to be "state". Even if I call it fips and the contents of the column are the state fips ID, the column MUST be named state. I named it fips and it did not work or even recognize that it existed. 

 

In the end I merged my data with the data from the plot example page because I knew for sure the plot example data worked, so all I had to do was get my state level data merged into it. An issue arose where they both had "State" as a column name, so I had to rename the nurses data state, because as mentioned before, the fips ID must be in a column named "state".

 

This was frustrating to figure out, but now that I know how it works it should be easier in the future.

 

 

* Get data 1;
filename test1234 url "https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-10-05/nurses.csv";

proc import out=nurses datafile=test1234 dbms=csv replace; 
	guessingrows = max; 
run;

data nurses;
	set nurses;
	where Year = 2020;
run;

* Renaming state column to something else to try to merge later with another dataset that has a STATE column too;
data nurses2;
   set nurses (rename=(State=StateNameFull));
run;
PROC SQL;
	create table work.nurse_fips3 as
	select t1.StateNameFull,
		   t1.'Total Employed RN'n,
		   t2.STATENAME,
		   T2.STATE,
		   T2.STATECODE
	from nurses2 t1
		left join sashelp.us_data t2 on (t1.StateNameFull = t2.statename);
quit;
data states;
  set maps.states;
  if state ^in(2,15,72);
  x = -x * 45/atan(1); 
  y =  y * 45/atan(1);
run;
data plot_data; set maps.uscenter; if state ^in(2,15,72) and ocean^='Y'; long = -long; statename = fipstate(state); run; title 'Total Employed RN by State, 2020'; proc sgmap mapdata=states maprespdata=work.nurse_fips3 plotdata=plot_data; esrimap url='http://services.arcgisonline.com/arcgis/rest/services/ Canvas/World_Light_Gray_Base'; choromap 'Total Employed RN'n / mapid=state density=2 name='choro'; text x=long y=lat text=statename / textattrs=(size=6pt); gradlegend 'choro' / title='Total Employed RN, 2020' extractscale; run; quit;

Indescribled_0-1633643690350.png

 

 

View solution in original post

5 REPLIES 5
Oligolas
Barite | Level 11

Hi,

unfortunately I do not have sgmap installed to test it and I'm not familiar with it, but I get everything to work until then.

I needed to add:

options validvarname=any;"

and to mount the maps libname

libname MAPS "C:\Program Files\SASHome\SASFoundation\9.4\maps";

 

Since you are in a "validvarname=any;" environment, does SGMAP maybe require a "SAS name literal" to work?

It's strange to me that SAS does not find the variable so, I'm afraid this is the only idea I have right now, maybe it's worth a test.

like this?

choromap 'Total Employed RN'n / mapid='fips'n density=2
________________________

- Cheers -

ballardw
Super User

The MAPS library I have from SAS/Graph does not have a MAPS.STATES data set.

Please show the Proc Contents result when run on MAPS.STATES.

You say you "checked via PROC PRINT to make sure fips is there". Which data set(s) did you check? There are three involved.

 

Note very closely that the example you borrowed from did not use FIPS but STATE as the MAPID variable and the programmer added that to the PLOT_DATA data set build from MAPS.USCENTER. The MAPS.USCENTER I have does not have a FIPS variable. What may be more important, is the USCENTER set, at least the one I have, only has state level data. If you are attempting to use FIPS at a level other than state then you may be wasting your time completely. Or share the Proc Contents from your MAPS.USCENTER.

 

I believe we may have mentioned that when you get an error then show the code from the log that generated the error message along with all the notes and messages from that procedure as well.

Indescribled
Obsidian | Level 7

Long response, but I tried to answer each of your questions!

 

Here is the output of

proc contents
	data = maps.states;
run;

Indescribled_5-1633623779145.png

When I ran PROC PRINT to look for the fips variable, I first checked the dataset in the example I linked to see how it was done there. The "state" variable is the FIPS id of the state, but the column title is state instead of fips. I assumed that meant that SAS required the FIPS number to plot it. 

Below is the output of 

proc print 
	data=sashelp.us_data;
run;

Indescribled_0-1633623167865.png

I ran the code below to confirm that my newly created table had the same format as the data used in the example. 

proc print 
	data=work.nurse_fips;
run;

Indescribled_1-1633623371332.png

 

Then, in the plot procedure, I replaced 

 

maprespdata= to my new data instead of the population data set

 

choromap to my data instead of the population data, instead of the population data in the example

 

mapid= my new fips variable, which was previously called "state" in the example

 

The data I am working with is only state level, there is no county data.

 

Here is:

proc contents
	data = maps.uscenter;
run;

Indescribled_2-1633623642431.png

 

Here are the exact errors/logs

Indescribled_3-1633623715195.pngIndescribled_4-1633623734421.png

 

Indescribled
Obsidian | Level 7

After a lot of trial and error I managed to get it to work. Here is the full working code and explanation if anyone else runs across this in the future:

 

The issue I seemed to be having was that choromap mapid=??? NEEDS to be "state". Even if I call it fips and the contents of the column are the state fips ID, the column MUST be named state. I named it fips and it did not work or even recognize that it existed. 

 

In the end I merged my data with the data from the plot example page because I knew for sure the plot example data worked, so all I had to do was get my state level data merged into it. An issue arose where they both had "State" as a column name, so I had to rename the nurses data state, because as mentioned before, the fips ID must be in a column named "state".

 

This was frustrating to figure out, but now that I know how it works it should be easier in the future.

 

 

* Get data 1;
filename test1234 url "https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-10-05/nurses.csv";

proc import out=nurses datafile=test1234 dbms=csv replace; 
	guessingrows = max; 
run;

data nurses;
	set nurses;
	where Year = 2020;
run;

* Renaming state column to something else to try to merge later with another dataset that has a STATE column too;
data nurses2;
   set nurses (rename=(State=StateNameFull));
run;
PROC SQL;
	create table work.nurse_fips3 as
	select t1.StateNameFull,
		   t1.'Total Employed RN'n,
		   t2.STATENAME,
		   T2.STATE,
		   T2.STATECODE
	from nurses2 t1
		left join sashelp.us_data t2 on (t1.StateNameFull = t2.statename);
quit;
data states;
  set maps.states;
  if state ^in(2,15,72);
  x = -x * 45/atan(1); 
  y =  y * 45/atan(1);
run;
data plot_data; set maps.uscenter; if state ^in(2,15,72) and ocean^='Y'; long = -long; statename = fipstate(state); run; title 'Total Employed RN by State, 2020'; proc sgmap mapdata=states maprespdata=work.nurse_fips3 plotdata=plot_data; esrimap url='http://services.arcgisonline.com/arcgis/rest/services/ Canvas/World_Light_Gray_Base'; choromap 'Total Employed RN'n / mapid=state density=2 name='choro'; text x=long y=lat text=statename / textattrs=(size=6pt); gradlegend 'choro' / title='Total Employed RN, 2020' extractscale; run; quit;

Indescribled_0-1633643690350.png

 

 

Oligolas
Barite | Level 11

Hi, 

the only differences I see right now is that you renamed fips to state and added Statecode to Nurse_fips3

Since there are no differences in Plot_data and only renaming changes in the SGMAP call, I presume the problem was that you need Statecode to get SGMAP to run.

I can not see why fips could be the problem unless SGMAP would actually expect this syntax, I don't know.

On the other hand I see that Guam's and Virgin Island's fips values are now missing, where they had values of respectively 66 and 78 before.

Maybe you'd like to look over this.

________________________

- Cheers -

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 5 replies
  • 866 views
  • 0 likes
  • 3 in conversation