使用substr将SAS中的宽数据转换为窄数据

时间:2016-10-25 15:13:04

标签: sas

enter image description here我在SAS中有一个广泛的数据集,每年的每个月都有不同的列,结构如下:" 2015年8月"通过" 2016年8月"。有些月份有两个下划线,有些有一个。基本上,我需要使用substr创建一个新的Month变量和一个Year变量,并且输出看起来像附加的输出。通常,我只会使用proc转置,但我们必须使用几个代码块和if-then语句来完成它。这是我在2015年8月尝试过的代码的截断版本。我收到了很多错误......

data work.jobs;
set DownL.Tabled1x2016;
    Industry=propcase(Industry);
    if substr(Aug__2015, length(Aug__2015),4)='2015' and not missing(Aug__2015) then do;
    Year=substr(Aug__2015, length(Aug__2015), 4);
    Month=substr(Aug__2015, 1, 3);
end;
run;

不知何故,对于一年中的每个月,我需要单独的if-then块,这会产生月份和年份的字符值。提前感谢您的指导。

enter image description here

2 个答案:

答案 0 :(得分:0)

使用和数组以及vname()函数。

data work.jobs;
set DownL.Tabled1x2016;
    format tmp $32.;
    array mths[*] Aug__2015 -- Aug__2016;
    Industry=propcase(Industry);
    do i=1 to dim(mths);
        tmp = compress(vname(mths[i]),'_');
        Month = substr(tmp,1,3);
        Year = substr(tmp,4);
        jobs = mths[i];
        output;
    end;
    drop tmp i Aug__2015 -- Aug__2016;
run;

array mths[*] Aug__2015 -- Aug__2016;这会创建一个变量数组,这些变量以Aug__2015开头,并以Aug_2016结尾。或者,您可以单独列出所有变量。

*是一张外卡,可让您无法定义数组大小 - 让SAS为您完成。

SAS Data Step数组只是指向表中变量的指针的逻辑结构。

答案 1 :(得分:0)

编辑:根据提供的样本数据进行更新。

%let months=Aug__2015*Sept__2015*Oct__2015*Nov__2015*Dec__2015*
  Jan__2016*Feb__2016*Mar__2016*Apr__2016*May_2016*
  June_2016*July_2016*Aug__2016;
%let fmonths=August*September*October*November*December*
  January*February*March*April*May*June*July*August;
%let fyears=2015*2015*2015*2015*2015*
  2016*2016*2016*2016*2016*2016*2016*2016;

DATA dset2;
  SET dset1;
  FORMAT month $9.;
  %do i=1 %to 13;
    %let var=%scan(&months., &i., *);
    %let fmonth=%scan(&fmonths., &i., *);
    %let fyear=%scan(&fyears., &i., *);
    IF NOT MISSING(&var.) THEN DO;
      jobs=&var.;
      month="&fmonth.";
      year=&fyear.;
      OUTPUT;
    END;
  %end;
RUN;

@ DomPazz的答案更清晰。这个更灵活。