首先我要指出的是,我是 SAS 新手。
我有一个图书馆,里面有一定数量的数据集。 该库不是 SAS 本机的,而是通过 ODBC 驱动程序连接到 SAS 服务器。我们称这个库为
extlib
。
我想获取一个输出数据集,其中包含
extlib
库中每个数据集的观察数量。换句话说,输出如下所示:
|
|
|
---|---|---|
extlib | 标签A | 1000 |
extlib | 标签B | 2000 |
extlib | 选项卡C | 0 |
extlib | 选项卡D | 1500 |
我了解到,对于“普通”库,即托管在 SAS DBMS 中的库,获取此类表相当容易,因为如果运行如下所示的命令,您可以在
sashelp.vtable
中找到它:
DATA want;
SET sashelp.vtable (WHERE=(libname="EXTLIB") KEEP=libname memname nobs);
RUN;
问题是当我在
extlib
上运行此专门过滤时,我得到以下结果:
|
|
|
---|---|---|
extlib | 标签A | . |
extlib | 标签B | . |
extlib | 选项卡C | . |
extlib | 选项卡D | . |
而其他库中的其他数据集确实在
nobs
中具有 sashelp.vtable
的值。
我怀疑该库来自国外的事实在这个问题上受到了威胁。
当我跑步时:
PROC SQL;
SELECT COUNT(*) AS nobs FROM extlib.tabA;
QUIT;
我获取特定桌子的信息。
问题是我在这个数据库中有大量的表,我只能通过 SAS 访问它们, 所以我的问题是:如何为库中的每个数据集获取这个结果?
最简单的方法是研究如何用他们所在系统的数据库语言进行等效的元数据查询。 那么你就可以调用该代码:
proc sql;
connect using EXTLIB;
create table want as select * from connection to EXTLIB
(... code that works in the foreign database ... )
;
quit;
否则,您将需要实际要求 SAS 计算有多少个观测值,然后用正确的答案更新 NOBS 列。 所以也许有这样的宏。
%macro contents(libref,out=contents);
proc sql noprint;
create table &out as
select
t.LIBNAME as LIBNAME label='Library reference'
,t.memname as MEMNAME label='Dataset name'
,t.MEMTYPE as MEMTYPE label='Dataset type'
,t.MODATE as MODATE label='Last mod datetime'
,t.nlobs as NOBS label='Number of observations'
,t.NVAR as NVAR label='Number of variables'
,t.OBSLEN as OBSLEN label='Observation length'
,t.memlabel as MEMLABEL label='Dataset label'
from dictionary.tables t
where t.libname = "%upcase(&libref)"
order by 1,2
;
%do %while(&sqlobs);
select libname,memname,catx('.',libname,nliteral(memname))
into :libname trimmed, :memname trimmed, :ds
from contents where missing(nobs)
;
%if (&sqlobs) %then %do;
update contents set nobs = (select count(*) from &ds)
where libname="&libname" and memname="&memname"
;
%end;
%end;
quit;
%mend;
我们来做个测试:
proc datasets nolist lib=work memtype=data kill;
run;
data x; do i=1 to 5; output; end; run;
data v/view=v; set x; where i<3 ; run;
option mprint;
%contents(work);
proc print;
run;
结果
OBS LIBNAME MEMNAME MEMTYPE MODATE NOBS NVAR OBSLEN MEMLABEL
1 WORK V VIEW 19JUN24:11:40:39 2 1 8
2 WORK X DATA 19JUN24:11:40:39 5 1 8
注意使用 DICTIONARY.TABLES 中的 NLOBS 变量,以便不计算数据集中任何已删除的观测值。
使用宏找到了“解决方案”和
CALL execute()
DATA rowCount; *creating an empty table to host row count info;
ATTRIB
tabName length=$255 format=$255. informat=$255.
nRows length=8 format=20. informat=20.;
STOP;
RUN;
/*
Macro-Function linking that inserts for each table from the 'extlib' library
the name of this table and the count of rows through a PROC SQL
*/
%MACRO countRows(tableName);
PROC SQL;
INSERT INTO rowCount
SELECT "&tableName." AS tabName, COUNT(*) AS nRows
FROM EXTLIB.&tableName.;
QUIT;
%MEND countRows;
/* Will execute countRows for every values of the 'memname' column */
DATA _NULL_;
SET ashelp.vtable (WHERE=(libname="EXTLIB"));
CALL execute('%countRows('||memname||');');
RUN;
更多的解决方法,但它解决了我的问题。