使用sas将宏转换为表或宏变量

时间:2014-06-20 14:50:12

标签: sql sas

我有这个宏。目的是从表格dicofr中获取变量的名称,并使用symput将行内部放入变量名称。

但是,某些内容无法正常工作,因为该变量& nvarname不会被视为变量。

这是dico&&pays&l

的内容
varname descr
var12   aza
var55   ghj
var74   mcy

这是dico&&pays&l..1

的内容
varname 
var12
var55
var74

以下是我的代码

%macro testmac;

%let pays1=FR ;

%do l=1 %to 1 ;

data dico&&pays&l..1 ; set dico&&pays&l (keep=varname); 
call symput("nvarname",trim(left(_n_))) ;
run ;


data a&&pays&l;
set a&&pays&l;
nouv_date=mdy(substr(date,6,2),01,substr(date,1,4));
format nouv_date monyy5.;
run;



proc sql;
create table toto 
(nouv_date date , nomvar varchar (12));
quit;

proc sql;

insert into toto SELECT max(nouv_date),"&nvarname" as nouv_date as varname FROM a&&pays&l WHERE (&nvarname ne .);


%end;

%mend;

%testmac;

附属问题。是否可以将varname和与该varname相关的日期转换为宏变量?我的男人 - 告诉我这个,但我以前从未这样做过。

提前致谢。

编辑: 我有这张桌子

date    col1 col2 col3 ... colx
1999M12 .    .    .        .
1999M11 .    2    .        .
1999M10 1    3    .        3
1999M9  0.2  3    2        1

我正在尝试知道具有最大日期的列的名称,知道列内部的值不同于缺失值。

对于col1,它将是1999M10。对于col2,它将是1999M11等......

2 个答案:

答案 0 :(得分:0)

在我看来,您正在尝试使用宏来生成INSERT INTO语句来填充表格。可以在不使用宏的情况下执行此操作,这是我建议的方法。

您可以使用datastep语句将INSERT INTO语句写出到文件中。然后在datastep之后,使用%include语句来运行该文件。

这将更容易编写/维护/调试,并且性能也会更好。

答案 1 :(得分:0)

根据您的更新,我认为以下代码可以满足您的需求。如果您不介意首先对输入数据集进行排序,您可以通过单个数据步骤获得所需的所有值 - 无需宏!

data have;
length date $7;
input date col1 col2 col3;
format date2 monyy5.;
date2 = mdy(substr(date,6,2),1,substr(date,1,4));
datalines;
1999M12 .    .    .   
1999M11 .    2    .   
1999M10 1    3    .   
1999M09 0.2  3    2   
;
run;

/*Required for the following data step to work*/
/*Doing it this way allows us to potentially skip reading most of the input data set*/
proc sort data = have;
  by descending date2;
run;

data want(keep = max_date:);
  array max_dates{*} max_date1-max_date3;
  array cols{*} col1-col3;
  format max_date: monyy5.;

  do until(eof); /*Begin DOW loop*/
    set have end = eof;

    /*Check to see if we've found the max date for each col yet.*/
    /*Save the date for that col if applicable*/
    j = 0;
    do i = 1 to dim(cols);
      if missing(max_dates[i]) and not(missing(cols[i])) then max_dates[i] = date2;
      j + missing(max_dates[i]);
    end;
    /*Use j to count how many cols we still need dates for.*/
    /* If we've got a full set, we can skip reading the rest of the data set*/
    if j = 0 then do;
      output;
      stop;
    end;
  end; /*End DOW loop*/
run;

编辑:如果你想在每个的最大日期旁边输出名字,可以稍微修改一下:

data want(keep = col_name max_date);
  array max_dates{*} max_date1-max_date3;
  array cols{*} col1-col3;
  format max_date monyy5.;

  do until(eof); /*Begin DOW loop*/
    set have end = eof;

    /*Check to see if we've found the max date for each col yet.*/
    /*If not then save date from current row for that col*/
    j = 0;
    do i = 1 to dim(cols);
      if missing(max_dates[i]) and not(missing(cols[i])) then max_dates[i] = date2;
      j + missing(max_dates[i]);
    end;
    /*Use j to count how many cols we still need dates for.*/
    /* If we've got a full set, we can skip reading the rest of the data set*/
    if j = 0 or eof then do;
      do i = 1 to dim(cols);
        col_name = vname(cols[i]);
        max_date = max_dates[i];
        output;  
      end;
      stop;
    end;
  end; /*End DOW loop*/
run;
相关问题