楼主: ertyuj
5916 8

[原创博文] 求一个宏:用于纵向合并数据文件 [推广有奖]

  • 0关注
  • 1粉丝

硕士生

25%

还不是VIP/贵宾

-

威望
0
论坛币
259 个
学术水平
0 点
热心指数
1 点
信用等级
0 点
经验
-417 点
帖子
128
精华
0
在线时间
157 小时
注册时间
2007-2-7
最后登录
2018-11-13

ertyuj 发表于 2011-2-18 08:22:15 |显示全部楼层
23论坛币
本帖最后由 wanghaidong918 于 2013-1-13 03:12 编辑

纵向合并多个数据文件的时候,例如
DATA newdata;
SET data1 data2 ... datan;
RUN;

使用这种方法合并数据文件,最终文件newdata中的变量属性与data1中相同。
如果原始数据文件data1 data2 ... datan某个(或者某些)变量的长度不同,那么合并后的数据文件内容很有可能会被截取。求一个宏,可以合并任意数目数据文件 data1 data2 ... datan,任意数目变量,newdata任意一个变量的长度均为data1 data2 ... datan中最大的值。
附件给出一个用于合并两个数据文件的例子。多谢。

macro.pdf

34.4 KB

本帖被以下文库推荐

stata SPSS
hopewell 发表于 2011-2-18 08:22:16 |显示全部楼层
  1. libname ben 'c:\Ben Xu\00 Temp_Testfolder';
  2. data ben.raw1;
  3.     length y $20;
  4.     input x y $;
  5. datalines;
  6. 1 xxxxxx
  7. 2 xxx
  8. 3 xxxxxxx
  9. ;
  10. data ben.raw2;
  11.     length y $10;
  12.     input x y $;
  13. datalines;
  14. 11 yyy
  15. 12 y
  16. 13 yy
  17. ;
  18. %macro union(lib=, out=work.out);
  19.     %local dsn;
  20.     proc sql noprint;
  21.         select catx('.',libname,memname) into: dsn separated by ' '
  22.             from sashelp.vmember
  23.             where libname=upcase("&lib") and memtype='DATA';
  24.         create table _temp as
  25.             select name, max(length) as length
  26.                 from sashelp.vcolumn
  27.                 where libname=upcase("&lib") and memtype='DATA' and type='char'
  28.                 group by name;
  29.     quit;
  30.     %let sasfile=%sysfunc(pathname(&lib))\combined.sas;
  31.     data _null_;
  32.         file "&sasfile";
  33.         set _temp end=last;
  34.         if _n_=1 then put "Data &out;";
  35.         put " length " name " $ " length 8. ";";
  36.         if last then do;
  37.             put " set &dsn;";
  38.             put "run;";
  39.         end;
  40.     run;
  41.     %include "&sasfile";
  42.     proc delete data=_temp;
  43.     run;
  44. %mend union;
  45. %union(lib=ben)
复制代码
观钓颇逾垂钓趣 种花何问看花谁
回复

使用道具 举报

ertyuj 发表于 2011-2-18 08:24:07 |显示全部楼层
求大侠提供或者帮着编写一个宏,可以合并任意数目数据文件 data1 data2 ... datan,任意数目变量,newdata任意一个变量的长度均为data1 data2 ... datan中相应变量长度的最大值。
回复

使用道具 举报

myzhang1982 在职认证  发表于 2011-2-18 11:00:43 |显示全部楼层
这个Macro应该可以解决你的问题
%macro fwords04(string=,
                root=,
                delim=,
                vnwords=nwords);
  %put ARROW SYSTEM MACRO FWORDS04: Separate a string into words.;
  %global &vnwords;
  %local count word spac;
  %let count=1;
  %if "&delim" ne ""
      %then %let spac=%str(&delim);
  %else %let spac=%str( );;
  %let word=%qscan(&string,&count,&spac);
  %do %while (&word ne);
      %global &root&count;
      %let &root&count=&word;
      %let count=%eval(&count+1);
      %let word=%qscan(&string,&count,&spac);
  %end;
  %let &vnwords=%eval(&count-1);
%mend fwords04;

%macro setdata(inds=, outds=);
%fwords04(string=&inds, root=data, vnwords=datan);
%do i=1 %to &datan;
proc contents
         data=&&data&i out=cont&i noprint;
run;
%end;

data cont;
         set %do i=1 %to &datan; cont&i %end;;
run;
proc sort data=cont; by name length; run;
data attrib;
         set cont;
         by name length;
         if last.name;
         if type=2 then length2='$'||put(length,best.-l);
         else if type=1 then length2=put(length,best.-l);
run;

proc sql noprint;
  select strip(name)||' label='||'"'||strip(label)||'"'||' length='||strip(length2)
  into: attribs separated by ' '
  from attrib
quit;
%put &attribs;
data &outds;
  attrib &attribs;
  set &inds;
run;
%mend setdata;
回复

使用道具 举报

hssnow 发表于 2011-2-18 20:38:35 |显示全部楼层
本帖最后由 hssnow 于 2011-2-18 20:47 编辑

下面的测试代码应该可以符合你的要求吧,code不是很简洁,见谅了~
  1. data hs.data1;
  2.     length a $ 3;
  3.     length b $ 2;
  4.     input a b;
  5. datalines;
  6. 111 11
  7. ;
  8. run;
  9. data hs.data2;
  10.     length a $ 4;
  11.     length b $ 1;
  12.     input a b;
  13. datalines;
  14. 2222 2
  15. ;
  16. run;
  17. data hs.data3;
  18.     length a $ 1;
  19.     length b $ 5;
  20.     input a b;
  21. datalines;
  22. 3 33333
  23. ;
  24. run;

  25. proc sql noprint;
  26.     create table hs.vcolumn as select memname,name,length
  27.         from sashelp.vcolumn
  28.         where memname like 'DATA%'
  29.         order by memname,name,length;
  30.     create table hs.temp as select name,max(length)    as max_length
  31.         from  hs.vcolumn
  32.         group by name;
  33.     select distinct memname,count(distinct memname) into : set_data1 - : set_data99, : set_num
  34.         from hs.vcolumn;
  35.     select name,max_length,count(name) into : set_var1 - : set_var99 ,: set_length1 - : set_length99, : var_num
  36.         from hs.temp;
  37. quit;

  38. %macro m_set;
  39. data hs.newdata;
  40.     %do i=1 %to &var_num;
  41.     length &&set_var&i $ &&set_length&i;
  42.     %end;
  43.     set
  44.     %do j=1 %to &set_num;
  45.     HS.&&set_data&j
  46.     %end;
  47.     ;
  48.     run;
  49. %mend  ;

  50. %m_set
复制代码
如果允许改变原数据集 data1...datan 的属性的话,可以直接批量修改各各个数据集中,变量长度为其中的最大值,再set,会简单点
My Blog: http:/hssnow.name/
宁静致远
回复

使用道具 举报

hssnow 发表于 2011-2-18 22:46:26 |显示全部楼层
本帖最后由 hssnow 于 2011-2-18 22:47 编辑

5# hopewell
哈哈,“select catx('.',libname,memname) into: dsn separated by ' ' from sashelp.vmember”,很nice啊,比我那个简单很多啊
My Blog: http:/hssnow.name/
宁静致远
回复

使用道具 举报

ertyuj 发表于 2011-2-20 16:53:22 |显示全部楼层
非常感谢各位大侠的鼎力相助,我将HOPEWELL的代码做了延伸,可以使用到变量长度,FORMAT和INFORMAT长度,如下:

LIBNAME BEN02 "F:\TEMP";

DATA BEN02.TEMP1;
ATTRIB Date LENGTH = 8 FORMAT = 8.0 INFORMAT = Date10. LABEL = "1THIS IS THE DATE";
ATTRIB Y1 LENGTH = 4 FORMAT = 4.0 INFORMAT = 4.0 LABEL = "1THIS IS THE SIZE";
ATTRIB COLOR LENGTH = $8 FORMAT = $8. INFORMAT = $8. LABEL = "1THIS IS THE COLOR";
INPUT Date Y1 COLOR;
DATALINES;
11Jan2010 123        R       
12Jan2010 223        G       
13Jan2010 323        B
;
RUN;

DATA BEN02.TEMP2;
ATTRIB Date LENGTH = 8 FORMAT = 8.0 INFORMAT = Date10. LABEL = "2THIS IS THE DATE";
ATTRIB Y1 LENGTH = 8 FORMAT = 5.1 INFORMAT = 5.1 LABEL = "2THIS IS THE SIZE";
ATTRIB COLOR LENGTH = $50 FORMAT = $50. INFORMAT = $50. LABEL = "2THIS IS THE COLOR";
INPUT Date Y1 COLOR;
DATALINES;
15Jan2010 12.3        RED12       
16Jan2010 22.3        GREEN       
17Jan2010 32.3        BLUE2
;
RUN;

%MACRO COMBINE01(Mydatalib = , Mycomdata = );

PROC CONTENTS DETAILS DATA=&Mydatalib.._ALL_ OUT = WORK.VarList;
RUN;

    %LOCAL datasetsnms;
    PROC SQL /*NOPRINT*/;
            SELECT CATX(".",libname,memname) into: datasetsnms SEPARATED BY " "
        FROM sashelp.vmember
                WHERE LIBNAME = UPCASE("&Mydatalib") and MEMTYPE = "DATA";

                CREATE TABLE WORK.Mytablenull AS
                SELECT NAME, TYPE,
                                        MAX(LENGTH) AS LENGTH,
                                        MAX(FORMATL) AS FORMATL, MAX(FORMATD) AS FORMATD,
                                        MAX(INFORML) AS INFORML, MAX(INFORMD) AS INFORMD
                FROM        WORK.VarList
                WHERE LIBNAME = UPCASE("&Mydatalib") AND MEMTYPE = "DATA"
                GROUP BY        NAME, TYPE;
        QUIT;
        PROC SQL;
        DESCRIBE TABLE WORK.Mytablenull;
        QUIT;

    %LET Mycomsas = %SYSFUNC(PATHNAME(&Mydatalib))\Mycomcode.sas;
       
    DATA WORK.Mydatanull;
                FILE "&Mycomsas";
               
                SET WORK.Mytablenull END = Mylastobs;
                IF _N_ = 1THEN PUT "Data &Mydatalib..&Mycomdata;";
                IF TYPE = 1 THEN PUT  "ATTRIB" +1 NAME "LENGTH = " LENGTH "FORMAT = " FORMATL +(-1) "." FORMATD "INFORMAT = " INFORML +(-1) "." INFORMD ";";
                IF TYPE = 2 THEN PUT  "ATTRIB" +1 NAME "LENGTH = " "$" LENGTH "FORMAT = " "$" FORMATL +(-1) "." FORMATD "INFORMAT = " "$" INFORML +(-1) "." INFORMD ";";
       
                IF Mylastobs =1 THEN DO;
                        PUT " SET &datasetsnms;";
                        PUT "RUN;";
                END;
        RUN;
    %INCLUDE "&Mycomsas";
%MEND COMBINE01;

%COMBINE01(Mydatalib = BEN02, Mycomdata = Mycombined);
回复

使用道具 举报

megan78 发表于 2011-9-3 16:33:14 |显示全部楼层
受教了,正在研究SAS
回复

使用道具 举报

ming0143 发表于 2012-9-14 17:57:26 |显示全部楼层
我也遇到了相同的问题,要合并三个数据库  数据库之间不同的变量出不来,跟楼主提问的情况一样。看了各位老师的宏,由于刚学SAS,实在看不懂该怎么弄的,现在着急合并中,各位大大,可以指教下么  我的QQ号是402776533
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 我要注册

GMT+8, 2018-12-10 06:53