楼主: 小鳄鱼a
4936 16

求助关于文件变量类型长度设定的问题 [推广有奖]

11
小鳄鱼a(未真实交易用户) 发表于 2016-4-19 20:44:32
guanglei 发表于 2016-4-19 19:13
如果是格式不一致造成的无法合并,可以在proc append中加一个force选项。
我写了一个宏程序,可以导入并合 ...
你跟我写的是一样的   




WARNING: 变量 _COL1 在 BASE 和 DATA 文件中的长度不同。 (BASE 64 DATA 78)。
WARNING: 变量 _COL2 在 BASE 和 DATA 文件中的长度不同。 (BASE 34 DATA 36)。
WARNING: 由于类型不匹配,未追加变量 _COL9。
WARNING: 由于类型不匹配,未追加变量 _COL10。
WARNING: 变量 _COL11 在 BASE 和 DATA 文件中的长度不同。 (BASE 24 DATA 26)。
WARNING: 变量 _COL12 在 BASE 和 DATA 文件中的长度不同。 (BASE 8 DATA 12)。

12
yingzi2003(未真实交易用户) 发表于 2016-4-19 22:03:19
导入所有的excel文件到SAS, output the contents, 建一个SAS DATASET包括文件名, 变量名, 数据类型, 找出哪几个变量有相同的名称,但不同的变量类型. 然后转换这些变量成字符型, 再合并.

13
yingzi2003(未真实交易用户) 发表于 2016-4-19 23:26:04
变量只有两种类型:字符和数字型. 日期只是format, 你可以合并数据后重新改变变量类型, 再加上你要的format. 我在最后加上了你的空数据集base_set, 以免字符型数据被切.


%let inxlsx_dir=path ;
FILENAME pipedir PIPE  "dir/b ""%unquote(&inxlsx_dir.)""  " LRECL = 400 ;
data filelist;
   infile pipedir length=linelen;
   length dataname $29. ContsName $32. ;
   input excelname $varying200. linelen;
   if find(excelname,'.xlsx') ;
   dataname=scan(excelname,1,'.') ;
   ContsName=strip(DataName)||"_ct" ;
run;

data _null_;
  set filelist ;
  call execute('PROC IMPORT OUT='||strip(dataname)||' DATAFILE= "&inxlsx_dir.\'||strip(excelname)||'" DBMS=xlsx REPLACE ;GETNAMES=YES; RUN;');
  call execute('PROC CONTENTS DATA='||strip(dataname)||' OUT='||strip(ContsName)||'(KEEP=name type) NOPRINT; RUN;') ;
run;

data _null_ ;
  set filelist end=eof ;
  if _n_=1 then call execute('data all_conts; set ') ;
  call execute(ContsName) ;
  if eof then call execute(';run;') ;
run ;

proc sort data = all_conts nodup ;
  by name type ;
run;

proc sql ;
  create table typechange as
  select distinct name
  from all_conts
  group by name
  having count(*) > 1 ;
quit ;

%MACRO uniform_var(inputdata=);
    proc contents data=&inputdata. noprint out=conts(keep=name type);
    run;

    proc sql ;
          create table typeconts as
          select r1.*
          from typechange as r2 join conts as r1
          on upcase(r1.name) = upcase(r2.name) ;
        quit ;

    proc sql noprint ;
          select distinct name into: nametype separated by ' '
          from typeconts ;
        quit ;

    data _null_;
        set typeconts end=eof;
        if _n_ = 1 then call execute("data &inputdata.2; set &inputdata.;");
        if type=1 then do;
            call execute("length _"||strip(name)||" $32.; ");
            call execute("_"||strip(name)||"=put("||strip(name)||", BEST32.);");
        end;
        if type=2 then call execute("length _"||strip(name)||" $32.; _"||strip(name)||"="||strip(name)||";");
        if eof then call execute("drop &nametype ; run; ");
    run;

    data _null_;
        set typeconts end=eof;
        if _n_ = 1 then call execute("data _&inputdata.; set &inputdata.2; rename ");
        call execute(" _"||strip(name)||" = "||strip(name)||" ");
        if eof then call execute("; run; ");
    run;
%MEND uniform_var;

data _null_;
    set filelist end=eof;
    call execute('%uniform_var(inputdata='||strip(dataname)||');');
run;

data _null_;
    set filelist end=eof;
        if _n_ = 1 then call execute('data combined ; set base_set ') ;  
    call execute('_'||strip(dataname));
        if eof then call execute(' ; run ;') ;
run;
已有 2 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
admin_kefu + 20 热心帮助其他会员
小鳄鱼a + 5 + 5 + 5 + 5 精彩帖子

总评分: 论坛币 + 25  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

14
小鳄鱼a(未真实交易用户) 发表于 2016-4-20 08:34:59
yingzi2003 发表于 2016-4-19 23:26
变量只有两种类型:字符和数字型. 日期只是format, 你可以合并数据后重新改变变量类型, 再加上你要的format. ...
非常感谢   能否传个txt或者 word    直接复制的话很多错误   对这些语法不是很熟悉  另外   我只需要将  %let inxlsx_dir=path ; 中的path改一下就可以把

15
yingzi2003(未真实交易用户) 发表于 2016-4-20 09:07:52
你需要改一下path. 还有就是要建一个空数集base_set, 但数据类型不能错, 要给足够length.
已有 1 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
小鳄鱼a + 5 + 5 + 5 + 5 精彩帖子

总评分: 论坛币 + 5  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

16
小鳄鱼a(未真实交易用户) 发表于 2016-4-20 09:55:55
yingzi2003 发表于 2016-4-20 09:07
你需要改一下path. 还有就是要建一个空数集base_set, 但数据类型不能错, 要给足够length.
谢谢     我的文件基本是  a (1) a (2) a (3) 或者 加中文与数字组合后的   比如  2013上 (1)  2013上 (2)之类的    主要是对excel可以用鼠标简单的批量命名   ,   但是给我的这个程序导入为sas数据集却不能这样命名  


NOTE: CALL EXECUTE 例程生成的行。
290 + PROC CONTENTS DATA=a (99) OUT=a (99)_ct(KEEP=name type) NOPRINT; RUN;
                            --
                            22
ERROR: 文件“WORK.A.DATA”不存在。
NOTE 155-205: CALL EXECUTE 例程生成的行。
290 + PROC CONTENTS DATA=a (99) OUT=a (99)_ct(KEEP=name type) NOPRINT; RUN;
                                       --
                                       22
ERROR 22-7: 选项名称“99”无效。

NOTE 155-205: CALL EXECUTE 例程生成的行。
290 + PROC CONTENTS DATA=a (99) OUT=a (99)_ct(KEEP=name type) NOPRINT; RUN;
                                          ---
                                          22
ERROR 22-322: 语法错误,期望下列之一: ;, CENTILES, DATA, DETAILS, DIR, DIRECTORY, FMTLEN, LIB, MEMTYPE, MT,
              MTYPE, NODETAILS, NODS, NOPRINT, ORDER, OUT, OUT2, SHORT, VARNUM.

17
yingzi2003(未真实交易用户) 发表于 2016-4-20 20:37:54
改一下这段程序, 加translate and compress去掉文件名里().

data filelist;
   infile pipedir length=linelen;
   length dataname $29. ContsName $32. ;
   input excelname $varying200. linelen;
   if find(excelname,'.xlsx') ;
   dataname=compress(translate(scan(excelname,1,'.'),' ','()')) ;
   ContsName=strip(DataName)||"_ct" ;
run;


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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-28 12:39