通过多个数据范围SAS循环proc转置

时间:2018-01-22 12:41:57

标签: loops sas transpose

我正在尝试将一系列范围从excel文件转换为SAS。 excel文件看起来像这样:

            31 Dec   01Jan   02Jan   03Jan   04Jan  
 Book id1    23       24      35      43      98  
 Book id2     3       4       5       4       1  

 (few blank rows in between)  

             05Jan   06Jan   07Jan   08Jan   09Jan  
 Book id1    14      100      30     23      58  
 Book id2    2       7        3      8       6  


 (and it repeats..)

我的最终输出应该有一个日期的第一列,然后是书ID的两个附加列:

  Date    Book id1    Book id2
  31 Dec   23           3
  01Jan    24           4
  02Jan    35           5
  03Jan    43           4
  04Jan    98           1
  05Jan    14           2
  06Jan    100          7
  07Jan    30           3
  08Jan    23           8
  09Jan    58           6

在这个特殊情况下,我要求一个更简单的方法:

  1. 导入和转置每个数据范围并用宏变量替换数据范围以单独导入和转置每个单独的范围
  2. 或者首先导入整个数据文件,然后创建一个循环 转换每个数据范围
  3. 代码我用于简单导入和转置特定数据范围:

               proc import datafile="&input./have.xlsx"  
                         out=want  
                         dbms=xlsx  replace;  
                         range="Data$A3:F5" ;  
                         run;  
    
                         proc transpose data=want  
                                out=want_transposed  
                   name=date;  
                   id A;  
                         run;  
    

    谢谢!

1 个答案:

答案 0 :(得分:0)

在Excel文件中分割为多个段或行块的数据行可以原始导入SAS,然后使用DATA Step处理为分类形式。

在此示例中,将样本数据放入文本文件并导入,使列名称为通用VAR-1 ... VAR- n 。然后在每行处理通用导入,每个导入单元输出一个SAS数据集行。

每个段中的列名都保留在临时数组中,只要遇到空白书ID,就会更新。

* mock data;
filename demo "%sysfunc(pathname(WORK))\demo.txt";

data _null_;
  input;
  file demo;
  put _infile_;
datalines;
        .,    31Dec,   01Jan,   02Jan,   03Jan,   04Jan  
 Book_id1,    23   ,   24   ,   35   ,   43   ,   98  
 Book_id2,     3   ,   4    ,   5    ,   4    ,   1  

        .,    05Jan,   06Jan,   07Jan,  08Jan,   09Jan  
 Book_id1,    14   ,   100  ,   30   ,  23   ,   58  
 Book_id2,    2    ,   7    ,   3    ,  8    ,   6  
run;

* mock import;
proc import replace out=work.haveraw file=demo dbms=csv;
  getnames = no;
  datarow = 1;
run;

ods listing;
proc print data=haveraw;
run;

当Excel导入时,如下所示:

Obs    VAR1        VAR2     VAR3     VAR4     VAR5     VAR6

 1                 31Dec    01Jan    02Jan    03Jan    04Jan
 2     Book_id1    23       24       35       43       98
 3     Book_id2    3        4        5        4        1
 4
 5                 05Jan    06Jan    07Jan    08Jan    09Jan
 6     Book_id1    14       100      30       23       58
 7     Book_id2    2        7        3        8        6

可以以转置方式处理,只输出与原始单元格对应的名称值对。

data have (keep=bookid date value);
  set haveraw;

  array dates(1000) $12 _temporary_ ;
  array vars var:;

  if missing(var1) then do;
    do index = 2 by 1 while (index <= dim(vars));
      if not missing(vars(index)) then 
        dates(index) = put(index-1,z3.) || '_' || vars(index);  * adjust as you see fit;
      else 
        dates(index) = '';
    end;
  end;
  else do;
    bookid = var1;
    do index = 2 by 1 while (index <= dim(vars));
      date = dates(index);
      value = input(vars(index),??best12.);
      output;
    end;
  end;    
run;