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.

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
  • 1828 views
  • 3 likes
  • 4 in conversation