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.
url='https://geocoding.geo.census.gov/geocoder/geographies/address?street=1600+Pennsylvania+Ave+NW&city=W...'
Try it with single quotes.
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.
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
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.
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;
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;
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.
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
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.
Ready to level-up your skills? Choose your own adventure.