我有以下代碼,該代碼由該論壇上的另一個用戶共享:
ods exclude all;
ods output nlevels=nlevels;
proc freq data=sashelp.cars nlevels;
tables _all_ / noprint ;
run;
ods select all;
proc contents data=sashelp.cars noprint out=contents;
run;
proc sql;
create table want(drop=table:) as
select c.varnum,c.name,c.type,n.*
from contents c inner join nlevels n
on c.name=n.TableVar
order by varnum
;
quit;
filename code temp;
data _null_;
set contents end=eof;
length nliteral $65 dsname $80;
nliteral=nliteral(name);
dsname = catx('.',libname,nliteral(memname));
file code;
if _n_=1 then put 'create table counts as select ' / ' ' @ ;
else put ',' @;
put 'nmiss(' nliteral ') as missing_' varnum
/',count(distinct ' nliteral ') as distinct_' varnum
;
if eof then put 'from ' dsname ';';
run;
proc sql;
%include code /source2;
quit;
proc transpose data=counts out=count2 name=name ;
run;
proc sql ;
create table want as
select c.varnum, c.name, c.type
, m.col1 as nmissing
, d.col1 as ndistinct
from contents c
left join count2 m on m.name like 'missing%' and c.varnum=input(scan(m.name,-1,'_'),32.)
left join count2 d on d.name like 'distinct%' and c.varnum=input(scan(d.name,-1,'_'),32.)
order by varnum
;
quit;
上面的代碼給出了以下輸出:
|Obs| VARNUM | NAME | TYPE| nmissing| ndistinct|
1 1 Make 2 0 38
2 2 Model 2 0 425
3 3 Type 2 0 6
...
我的問題是上述代碼的以下部分做了什么:
filename code temp;
data _null_;
set contents end=eof;
length nliteral $65 dsname $80;
nliteral=nliteral(name);
dsname = catx('.',libname,nliteral(memname));
file code;
if _n_=1 then put 'create table counts as select ' / ' ' @ ;
else put ',' @;
put 'nmiss(' nliteral ') as missing_' varnum
/',count(distinct ' nliteral ') as distinct_' varnum
;
if eof then put 'from ' dsname ';';
run;
proc sql;
%include code /source2;
quit;
有人可以解釋一下上述代碼部分的每一行都在做什么嗎?謝謝你。
uj5u.com熱心網友回復:
SAS 資料步驟是撰寫報告檔案的好工具。在這種情況下,正在撰寫的報告是 SAS 代碼。
filename code temp;
創建一個臨時檔案并將 fileref CODE 指向該位置。
data _null_;
開始一個不寫出資料集的資料步驟。
set contents end=eof;
當到達檔案末尾時,從資料集 CONTENTS 中讀取并將變數 EOF 設定為 true。
length nliteral $65 dsname $80;
定義兩個字符變數。
nliteral=nliteral(name);
將變數 N??LITERAL 設定為存盤在 NAME 變數中的當前變數名稱的名稱文字字串版本。
dsname = catx('.',libname,nliteral(memname));
將變數 DSNAME 設定為 LIBNAME 和 MEMNAME 變數中指定的資料集的名稱。
file code;
將 PUT 訊息定向到 fileref CODE,而不是默認將它們發送到 SAS 日志。
if _n_=1 then put 'create table counts as select ' / ' ' @ ;
else put ',' @;
將 SQL CREATE TABLE 陳述句的開頭寫入檔案的第一行。否則,在將由下一條陳述句寫入的下一組列之前寫入一個逗號。
put 'nmiss(' nliteral ') as missing_' varnum
/',count(distinct ' nliteral ') as distinct_' varnum
;
撰寫代碼以生成兩個變數。這些變數被命名為 MISSING_xx 和 DISTINCT_xx,其中 XX 部分是變數在存盤在 VARNUM 資料集中的原始資料集中的位置編號。NLITERAL 變數用于列印要匯總的變數的名稱。
if eof then put 'from ' dsname ';';
當到達檔案結尾時,寫入 CREATE TABLE 陳述句的結尾部分。
run;
結束資料步驟定義。
proc sql;
啟動 PROC SQL。
%include code /source2;
運行前一個資料步驟寫入 fileref CODE 的 CREATE TABLE 陳述句。
quit;
結束 PROC SQL 步驟。
uj5u.com熱心網友回復:
這似乎是使用資料集動態創建 SQL 代碼contents并將其保存到名為code. 這用于以下 SQL 陳述句:
proc sql;
%include code /source2;
quit;
檔案名code包含 SQL 代碼。%include抓取該代碼并將其放入程式中。他們本可以使用宏變數來做到這一點,但我假設代碼必須太長,以至于無法放入單個宏變數中。相反,他們選擇使用臨時檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/526370.html
標籤:循环sas
