在数据集(SAS)中添加变量(列)

时间:2018-06-01 09:22:35

标签: macros sas dataset add

我找不到这个简单问题的解决方案:我想在我的数据集中添加一个colum / variable。此变量将始终具有相同的值,存储在宏变量和值中。我在一个宏中,所以我不知道它是否会改变任何东西......这是合并2个数据步之前的步骤。 到目前为止,这就是我所拥有的:

%do i=1 %to 10;
    data &new_data_set;
        set &new_data_set;
        Nom_controle=&Nom_Controle;
        Partenaire=&Partenaire;
    run;
%end;

我正在尝试将一个名为“Nom_Controle”的列/变量添加到我的数据集(之前在宏中定义为& new_data_set),该列/变量始终采用存储在宏变量& Nom_controle中的值(之前也定义了)。我还试图添加名为“Partenaire”的第二列/变量,它始终采用存储在宏变量& Partenaire(之前定义的)中的值。 当然,正如我在这里发帖,我的代码不起作用。你能救我吗?

编辑:有些人问我为了帮助我,这里是代码的宏(完整的东西):

%macro presence_mouvement (data_set_detail_mouvement, data_set_mouvement);
    %if %sysfunc(exist(&data_set_mouvement)) AND %sysfunc(exist(&data_set_detail_mouvement)) %then %do; *Check if my data set actually exist;
        %let suffix=_2;
        %let new_data_set=&data_set_detail_mouvement&suffix; *Create the name of the new data set I'm going to save the result of the next proc sql in;
        proc SQL noprint; *Proc to look for errors in a previous data set and print it in the new data set;
                create table &new_data_set as
                insert into &new_data_set 
                SELECT num_mouvement 
                FROM &data_set_detail_mouvement
                EXCEPT 
                    SELECT num_mouvement
                    FROM &data_set_mouvement);

        %let Nom_controle=Presence_mouvement; *Creation of a new variable;
        %if %sysfunc(length(&data_set_detail_mouvement))=29 %then %do; *Creation of a second variable (value conditionnal to the size of a previous variable);
            %let Partenaire=%sysfunc(substr(&data_set_detail_mouvement, 9, 3)); %end;
        %else %if %sysfunc(length(&data_set_detail_mouvement))=30 %then %do; 
            %let Partenaire=%sysfunc(substr(&data_set_detail_mouvement, 9, 4)); %end;
        %else %do;
            %let Partenaire=%sysfunc(substr(&data_set_detail_mouvement, 9, 6)); %end;

        %do i=1 %to 10;
            data &new_data_set;
                set &new_data_set;
                Nom_controle=&Nom_Controle;
                Partenaire=&Partenaire;
            run;
        %end; 
    %end;*End of the actions to do in case the two data set in parameters exist;

%else %do; *Actions to do in case the two data set in parameters don't exist;
  data _null_;
     file print;
     put #3 @10 "At least one of the data set does not exist";
  run;
%end;
*This macro is aiming at pointing error in a previous data set, print them in a new data set and add two new variables/columns to this new data set (indicating their origin). The next set is going to be to merge this new data set to another one;
%mend presence_mouvement;

%presence_mouvement (sasuser.bgpi__detail_mouvement, sasuser.bgpi__mouvement);

我还想说我在尝试添加新变量之前测试了宏的其余部分,因此宏的其余部分应该没有任何问题。但谁知道......

2 个答案:

答案 0 :(得分:0)

创建变量的代码部分似乎没有错。如果没有看到整个代码或日志,可能还有其他问题很难从这个提取中分辨出来。例如,如果Nom_controle和Partenaire是字符变量,因为宏变量是字符但没有引号,那么肯定会有错误。您应该使用symbolgenmprint选项,然后发布日志以帮助解决问题。

答案 1 :(得分:0)

运行单个数据步骤,将新变量设置为宏变量中的值设置。如果值设置本质上是字符,则数据步骤变量需要在双引号内解析那些宏变量。

data &new_data_set;
  set &new_data_set;
  retain 
    Nom_controle "&Nom_Controle"
    Partenaire   "&Partenaire"
  ;

  * also works;
  * Nom_controle = "&Nom_Controle";
  * Partenaire   = "&Partenaire"; 
run;

注意:新的数据集变量长度将设置为宏变量中存储的值的长度。

数据集是值的矩形。它将具有一定数量的数字和/或字符类型的行和列。 DATA步骤中的SET语句将表格列的一行读入正在运行的程序数据向量中 - 这些数据向量基本上是DATA步骤中的变量。 DATA步骤自动循环并在各种条件下自动停止,例如正在读取的SET表的最后一行。

我不知道为什么你有一个宏循环%DO I=1 %TO 10。我可能会推测你认为你需要这样做才能更新' & new_data_set中有10行。

它到底在做什么?运行相同的代码10次!没有宏,实际的代码运行类似于以下

data x; do r = 1 to 10; output; end; run;  %* an original new_data_set;

data x; set x; z=1; run;
data x; set x; z=1; run;
data x; set x; z=1; run;
...

另一个问题是诸如

之类的代码
    %if %sysfunc(length(&data_set_detail_mouvement))=29 %then %do; *Creation of a second variable (value conditionnal to the size of a previous variable);
        %let Partenaire=%sysfunc(substr(&data_set_detail_mouvement, 9, 3)); %end;

您似乎从完全限定的 libname.dataset 中获取数据集名称的前3个,4个或6个字母,其中libname被假定为sasuser

可以是更安全,更健壮的版本
%let syslast = &data_set_detail_mouvement;
%let libpart  = %scan(&syslast,1,.); 
%let datapart = %scan(&syslast,2,.);
… extract 3, 4, or 6 preface of datapart … 
%* this might be helpful;
%let Partenaire = %scan(&datapart,1,_);