データセットのレコード数を取得する方法
(オブザベーション数、データセットが何行あるのかを数える)
dataステップやSQL,sas関数,Luaプロシジャなど様々な方法で取得できる
例としてsashelp.CLASSのレコード数を数えてみる
※オブザベーション数をマクロ変数に格納
open関数,attrn関数
%let Dataset = %sysfunc( open( sashelp.CLASS ) );
%let N1 = %sysfunc( attrn( &Dataset. , nlobsf ) );
%let rc = %sysfunc( close( &Dataset. ) );
%put N1 = &N1.;
必ずcloseすること
8桁以上でもEとか出ない
where使用可能(whereなしよりかは遅くなる)、関数使うとき注意が必要
SQL intoを使用
proc Sql noprint;
select count(*) into : N2 trimmed
from sashelp.CLASS;
quit;
%put N2 = &N2.;
trimmedでいらないブランクを消す(数値変数も文字としてマクロに格納されるため数値はブランク発生)
group byでN1 - N2などと複数のマクロ変数に格納する場合はtrimmedは×(ブランクも出てこない)
8桁以上だとE使われる
put( count(*) , best12. )とかにすればEにならない
where使用可能(whereなしよりかは遅くなる)
dataステップ1
data _null_;
if 0 then set sashelp.CLASS nobs = N;
call symputx( "N3" , N );
stop; * 無限ループ回避 *;
run;
%put N3 = &N3.;
where使用不可(エラーにはならないが、whereなしのレコード数がカウントされる)
nobsがそもそものデータセットのレコード数を取っているためだと思われる
dataステップ2
data _null_;
set sashelp.CLASS end = EOF;
if EOF = 1 then call symputx( "N4" , _N_ );
run;
%put N4 = &N4.;
レコードの数だけ処理を繰り返すため、おすすめしない
自分は、各行ごとに変数値などをマクロ変数にいれて、マクロでループ処理したりするときに使ったりする
Luaプロシジャ
%let Dataset = sashelp.CLASS;
proc Lua;
submit" Dataset = '&Dataset.' ";
local dsid = sas.open( Dataset )
local N = sas.nobs( dsid )
sas.close( dsid )
sas.symput( "N5" , N )
-- sas.submit( [[ %global N5; %let N5 = @N@; ]] )はダメっぽい
endsubmit;
run;
%put N5 = &N5.;
Luaプロシジャ全然知らないが、計算速いようなのでちょっとリファレンス調べてみた
適当に20億行のデータ作ってレコード数を数えてみたが、
open&attrn,SQL,if 0 then,Luaは高速だった
※whereしながらカウントする場合はちょっと遅くなる
https://support.sas.com/documentation/cdl_alternate/ja/lefunctionsref/67960/HTML/default/p12uchp7hm5h2zn1om2ut816af7h.htm
https://documentation.sas.com/?docsetId=mcrolref&docsetTarget=n0s4xeo2nzqhdtn177qgad6iz69f.htm&docsetVersion=9.4&locale=ja
https://support.sas.com/documentation/cdl_alternate/ja/mcrolref/67912/HTML/default/n1y2jszlvs4hugn14nooftfrxhp3.htm
http://support.sas.com/documentation/solutions/base/lua/9.4/proclua.pdf
https://support.sas.com/resources/papers/proceedings15/SAS1561-2015.pdf