BookmarkSubscribeRSS Feed
lichee
Quartz | Level 8

Hi all,

 

I'm trying to get geo info like census tract given a list of addresses through the site Census Geocoder, but cannot make PROC HTTP work so far. 

 

Below is the code I have for the address of white house, 1600 Pennsylvania Ave NW,Washington, DC, 20500

 

filename response temp;
proc http
url="https://geocoding.geo.census.gov/geocoder/geographies/address?street=1600+Pennsylvania+Ave+NW&city=W..."
method="GET"
out=response;
run;
libname resp json fileref=response;

 

I got the warning messages as below:

 

WARNING: Apparent symbolic reference STATE not resolved.
WARNING: Apparent symbolic reference STATE not resolved.
WARNING: Apparent symbolic reference BENCHMARK not resolved.
WARNING: Apparent symbolic reference VINTAGE not resolved.
WARNING: Apparent symbolic reference FORMAT not resolved.

 

Additionally, I have about 100 addresses that I need to loop through. How can I set loop through using the address data set as below:

data address;
infile datalines dlm=',' dsd;
input id $ street $ city $ state $ zip $;
datalines;
1,1600 Pennsylvania Ave NW,Washington,DC,20500
2,1234 Main street, City, DC, 12345
;
run;

Any suggestions are greatly appreciated!

L.

6 REPLIES 6
data_null__
Jade | Level 19
url='https://geocoding.geo.census.gov/geocoder/geographies/address?street=1600+Pennsylvania+Ave+NW&city=W...'

Try it with single quotes.

lichee
Quartz | Level 8

I believe it works with single quote, but I'm not sure how to interpret the log. The log was generated as in the screenshot below but no dataset or anything else. I thought it would write out geo info in certain form -- sorry that I'm accessing URL from SAS for the first time.

 

lichee_0-1743648614856.png

29 filename response temp;


30 proc http
31 url='https://geocoding.geo.census.gov/geocoder/geographies/address?street=1600+Pennsylvania+Ave+NW&city=W...
31 ! te=DC&zip=20500&benchmark=Public_AR_Current&vintage=Current_Current&format=json'
32 method="GET"
33 out=response;
34 run;

NOTE: 200 OK
NOTE: PROCEDURE HTTP used (Total process time):
real time 0.30 seconds
cpu time 0.01 seconds

35 libname resp json fileref=response;
NOTE: JSON data is only read once. To read the JSON again, reassign the JSON LIBNAME.
NOTE: Libref RESP was successfully assigned as follows:
Engine: JSON
Physical Name: /saswork/SAS_workF4AE001C33F4_pd-sas-grd7.awscloud.cms.local/#LN00134

LinusH
Tourmaline | Level 20

When it comes to the WARN,INGs, SAS tries to interpret all words that is prefixed with the &-sign as a macro variable, unless they are within single qoutes, or dealt with using a macro masking function.

Data never sleeps
BrunoMueller
SAS Super FREQ

I would use the QUERY=() option, this allows to specify the name=value pairs in an easy way.

See example:

filename resp temp;
proc http
url="https://geocoding.geo.census.gov/geocoder/geographies/address"
method="GET"
query=(
"street" = "1600 Pennsylvania Ave"
"city" = "Washington"
"state" = "DC"
"format" = "json"
"benchmark" = "4"
"vintage" = "4"
"returntype" = "geographies"
"searchtype" = "address"

)

out=resp
verbose
;
run;
%put %sysfunc(jsonpp(resp, log));

As for the second question, pass a file with address lines, have a look at this example

filename addr temp;
data _null_;
  infile datalines;
  input;
  file addr;
  ll = length(_infile_);
  put _infile_ $varying256. ll;
datalines;
1,1600 Pennsylvania Ave NW,Washington,DC,20500
2,1234 Main street,City,DC,12345
;

filename resp temp;
proc http
  method="POST"
  url=https://geocoding.geo.census.gov/geocoder/locations/addressbatch 
  in=multi form (
    "addressFile" = addr filename="local.csv" header="Content-Type: application/octet-stream" 
    , "benchmark" = "2020" nofilename header="Content-Type: text/plain" 
  )
  out=resp
  verbose
;
  debug level=0;
run;


data _null_;
  infile resp;
  input;
  putlog _infile_;
run;
lichee
Quartz | Level 8

Thanks a lot! 

 

The first part works well. For the second part for a list of addresses, based on the log requesting entering "vintage" info, I modified the code your provided slightly as below,  but still get "400 Bad Request". 

 

proc http
method="POST"
url="https://geocoding.geo.census.gov/geocoder/geographies/address"
in=multi form (
"addressFile" = addr filename="local.csv" header="Content-Type: application/octet-stream"
, "benchmark" = "4", "vintage" = "4" nofilename header="Content-Type: text/plain"
)
out=resp
verbose
;
debug level=0;
run;

lichee_0-1743705617979.png

 

BrunoMueller
SAS Super FREQ

The URL to be used ends in addressbatch,  see https://geocoding.geo.census.gov/geocoder/Geocoding_Services_API.html#_Toc172117435

 

Each --form option of the curl command must be specified as a comma separated list using the IN=MULTI FORM( ..., ..., ...) option of Proc HTTP.

Here is a working example using the same file as in the previous example as input:

filename resp temp;
proc http
  method="POST"
  url="https://geocoding.geo.census.gov/geocoder/geographies/addressbatch"
  in=multi form (
    "addressFile" = addr filename="local.csv" header="Content-Type: application/octet-stream" 
    , "benchmark" = "4" nofilename header="Content-Type: text/plain" 
    , "vintage" = "4" nofilename header="Content-Type: text/plain" 
  )
  out=resp
  verbose
;
  debug level=0;
run;

I have used the curl --trace tracefile.txt ... command to see how the information was passed and adapted the options for the IN=MULTI FORM( ..., ..., ...) option accordingly.

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 1650 views
  • 3 likes
  • 4 in conversation