daijp73 发表于 2019-12-30 16:03:44

SAS数据集多行合并为1行,以及文本还原为多行

本帖最后由 daijp73 于 2019-12-30 16:14 编辑

sas数据集合并代码:

/*
功能说明:SAS 数据集多行合并为1行输出。
功能调用:%nline(sds=,tds=,n=); 入口在文档尾部。
输出还原:还原方法参考 <a href="https://www.saihu.com/thread-2495-1-1.html">https://www.saihu.com/thread-2495-1-1.html</a>
联系:建议意见可联系微信号 daijp1971
*/

/*
宏 :%renfileds(ds=,prefix=);
功能:SAS 数据集变量批量改名为 prefix + 原变量名。
参数:
ds: 数据集
prefix: 新变量名前缀
步骤:
        获得数据集ds的所有字段。
        逐一改名。
联系:建议意见可联系微信号 daijp1971
*/
%macro renfileds(ds=,prefix=);
%if %length(%sysfunc(compress("&ds.","."))) ne %length(%sysfunc(compress("&ds.","")))
%then
        %do;
        %let libname=%scan("&ds.",1,".");
        %let memname=%scan("&ds.",2,".");
        %end;
%else
        %do;
        %let libname=WORK;
        %let memname=&ds.;
        %end;

proc sql noprint;
select name into :fieldnames separated by ' '
from dictionary.columns where libname=upcase("&libname") and memname=upcase("&memname") order by varnum;
quit;

data &ds;
set &ds;
%local i;
%let i=1;
%do %until (%scan(&fieldnames.,&i.," ")=);
%let oldname=%sysfunc(compress(%scan("&fieldnames",&i," ")));
rename &oldname=&prefix.&oldname;
%let i=%eval(&i.+1);
%end;
run;
%mend;

/*
宏:%nline(sds=,tds=,n=);
功能:SAS 数据集多行合并为1行输出。
参数:
sds: 源数据集
tds: 目标数据集
n: n行合并为1行
步骤:
        将sds切分为n个临时表
        将n个临时表合并为tds
注意:
        过程中需要建立和删除n个临时表 XXX0 XXX1...XXXn-1 ,XXX可定义
联系:建议意见可联系微信号 daijp1971
*/
%let XXX=T;
%macro nline(sds=,tds=,n=);
%local i;
%do i=0 %to &n-1;
        data &XXX._&i;
        set &sds;
        if mod(_n_,&n)=&i;
        run;
%end;

%do i=0 %to &n-1;
        %renfileds(ds=&XXX._&i,prefix=&XXX.&i);
%end;

data &tds;
merge %do i=1 %to &n-1; &XXX._&i %end; &XXX._0;
run;

proc datasets nolist;
%do i=0 %to &n-1;
        %put "#### delete: &XXX._&i";
        delete &XXX._&i;
%end;
run;
%mend;

/* ---------------------------------功能调用点------------------------------- */
%nline( sds=mapsgfk.us_counties, tds=tb, n=10 );

合并数据集,导出文本文件后,可以使用 gawk 工具执行如下脚本,将1行格式还原为多行格式。awk脚本如下:

{
        if (NR==1) { fieldwidth=int(NF/n); }       
        for (i=1;i<=NF;i++)
        {
                printf "%s",$i > tofile ;
                if (i%fieldwidth==0) { printf "\n" > tofile ; } else { printf "%s",FS> tofile; }
        }
}
gawk调用方式:
gawk -f 1line.awk -v n=4 -v tofile=out.txt -v FS=',' s1.dat

附件包含所有源代码,以及gawk工具。如有意见建议微信 daijp1971。

页: [1]
查看完整版本: SAS数据集多行合并为1行,以及文本还原为多行