如何在 SAS EG 的循环中向 API 发送、接收和收集数据?

How can I send, receive and collect data to and from API in a loop in SAS EG?

我想使用不同的字符串(地址)向 API 发出 GET 请求以获取相应的坐标。 API 一次只允许发送一个字符串。因此,我需要遍历我的“地址”变量,并希望在新的 variable/column.

中收集接收到的数据

由于我是 SAS EG 的新手,所以我对适当的方法(宏或“do-loops”)感到困惑。我非常感谢这里的任何帮助。我根据对 :

的回复起草了以下适用于单个字符串的解决方案
filename response temp;
filename headers temp;
url = 'https://api3.geo.admin.ch/rest/services/api/SearchServer?searchText=Bahnhofstrasse 1 Zürich&type=locations'
method='GET'
proxyhost = 'OUR PROXYHOST'
proxyport = *OUR PROXYPORT*
out= response
headerout = headers
ct = "application/json";
run;


data _null_;
  infile headers;
  input; 
  put _infile_;
run;

data _null_;
  infile response;
  input;
  put _infile_;
run;

* libref name same as fileref pointing to json content;
libname response json;

proc copy in=response out=work;
run;

对于如何从现在开始继续以及使用哪种方法的任何帮助,我将不胜感激。

您可以使用 doSubL 函数在辅助会话中为数据集中的每一行提交源代码。

示例:

* control data, a table of addresses to process;

data addresses;
length address 0;
input address $CHAR100.;
infile datalines truncover;
datalines;
Pennsylvania 6-5000 Millertown
Bahnhofstrasse 1 Zürich
;
*
Duebendorfstrasse 223 8051 Zürich
Hohlstrasse 451, Zurich 8048
Rotbuchstrasse 1, Zurich 8006
Froehlichstrasse 37, Zurich 8008
;

/*
 * a macro for 
 * - retrieving the search response,
 * - extracting the lat and lon,
 * - appending to all results table
 */

%macro get_lat_lon(address);
  %local server search_endpoint;

  %let server = https://api3.geo.admin.ch;
  %let search_endpoint = /rest/services/api/SearchServer;

  filename response temp;
  filename headers temp;

  * GET the search response;

  proc http
    url = "&server.&search_endpoint.?type=locations%str(&)searchText=&address"
    method = "get"
/*    proxyhost = ... */
/*    proxyport = ... */
    out = response
    headerout=headers
    ct = "application/json"
  ;
  run;

  libname response json;  /* Note: LIBREF is same as FILEREF */

  * copy data from JSON response to tables as inferred by json library engine;

  proc copy in=response out=sandbox;
  run;

  * add the address (the search term) to the results;

  %if %sysfunc(exist(sandbox.results_attrs)) %then %do;
    data sandbox.lat_lon / view=sandbox.lat_lon;
      length address 0 detail 0;
      set work.results_attrs (keep=detail lat lon);
      address = symget('address');
    run;
  %end;
  %else %do;
    data sandbox.lat_lon;
      length address 0 detail 0;
      address = symget('address');
      call missing(lat, lon);
      detail = 'No detail found for address';
    run;
  %end;

  * append new results (or lack thereof);

  proc append base=address_lookup_results data=sandbox.lat_lon;
  run;

  * clean out the sandbox;

  proc datasets nolist kill lib=sandbox;
  run; quit;

  filename response;
  filename headers;
%mend;

* create new table to contain appended results;

proc sql;
  create table address_lookup_results
  ( address char(100)
  , lat num
  , lon num
  , detail char(200)
  );

* create new folder to contain tables copied from json response;
* sandbox folder is under WORK so it will be automatically deleted when SAS session ends;

%let workpath = %sysfunc(pathname(WORK));
%let rc = %sysfunc(DCREATE(sandbox,&workpath));
libname SANDBOX "&workpath./sandbox";

* process each address in the control data;

data _null_;
  set addresses;

  length macro_call_source_code 0;

  * codegen;
  macro_call_source_code = cats('%get_lat_lon(%str(',address,'))');

  * submit codegen in side session;
  rc = dosubl (macro_call_source_code);
run;

libname sandbox;

附加在一起的结果图像。
  • 请注意 'not found' 详细信息,某些搜索结果包含给定地址的多个详细信息。如果您在编写必须选择 'best' 可能的详细信息对应于地址的代码时遇到问题,请打开一个新问题。


从响应中复制的中间 table SANDBOX.RESULTS_ATTRS 的内容。
  • 请注意,附加结果中仅使用了编号为 7、8 和 11 的变量(londetaillat)table WORK.ADDRESS_LOOKUP_RESULTS