根据第一行

时间:2016-02-10 19:25:02

标签: sas

我有这样的数据集:

DATA HAVE;
   INPUT A $ B $ C $ D $  ;
   DATALINES;
VAR1 VAR2 VAR3 VAR4
cat dog cat dog
dog cat cat dog
dog cat cat cat
;
RUN;

我希望将该数据集转换为类似于:

DATA WANT;
   INPUT VAR1 $ VAR2 $ VAR3 $ VAR4 $  ;
   DATALINES;
cat dog cat dog
dog cat cat dog
dog cat cat cat
;
RUN;

我可以申请完成此任务吗?基本上,我想将列重命名为第1行中的相应值,以及删除第1行。

为了给这个奇怪的请求提供一些上下文,我正在导入一个格式不好的xls。

2 个答案:

答案 0 :(得分:4)

使用第一行中的值生成一组可在RENAME语句或RENAME =选项中使用的OLD = NEW值。

proc transpose data=have(obs=1) out=names ;
  var _all_;
run;

如果列表足够短,您可以使用单个宏变量来完成。

proc sql noprint ;
  select catx('=',_name_,col1) 
    into :rename separated by ' '
    from names
  ;
quit;

然后你可以使用宏变量。

data want ;
  set have (firstobs=2 rename=(&rename));
run;

答案 1 :(得分:2)

如果使用proc transpose并且第一行的任何值的长度超过32个字符,则在rename中使用时,它们将是无效的变量名。

因此,proc transpose的替代方法是使用数组和数组函数来构建重命名列表。

data cols ;
  set have (obs=1) ;
  array vars{*} $32. _CHARACTER_ ;
  do nvar = 1 to dim(vars) ;
    curr_varname = vname(vars{nvar}) ; /* get the current variable name, e.g. A B etc */
    new_varname = vars{nvar} ; /* variable value, e.g. VAR1 VAR2 etc */
    output ;
  end ;
run ;

然后按照与Tom相同的方法将旧/新对转换为宏变量以嵌入rename=(...)语句。

proc sql ;
  select catx('=',curr_varname,new_varname) into :RENAMELIST separated by ' '
  from cols ;
quit ;

data want ;
  set have (firstobs=2 rename=(&RENAMELIST)) ;
run ;