1
votes

I can't find the solution for this simple problem: I want to add a colum/variable in my data set. This variable will always have the same value, stored in the macro variable &value. And I am in a macro so I don't know if it change anything... This is the step before merging 2 data step. So far, here's what I have:

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

I'm trying to add to my data-set (which was previously defined in the macro as &new_data_set) a column/variable named "Nom_Controle" which always takes the value stored in the macro variable &Nom_controle (previously defined too). I'm also trying to add a second column/variable named "Partenaire" which always takes the value stored in the macro variable &Partenaire (previously defined too). Of course, as I'm posting here, my code doesn't work. Can you help me?

EDIT: after some ask me to in order to help me, here is the macro this code is from (the full thing):

%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);

I also wanted to say that I tested the rest of the macro before trying to add new variable so the rest of the macro shouldn't have any problem. But who knows...

2
Your code shows a SET statement, not a MERGE. The macro %DO loop is not using the macro index variable &I, so you are doing the same data step 10 times. The phrase my code doesn't work is similar to my car doesn't work. Show the log message if there are warnings or errors, or better describe the condition of doesn't work. Expand the shown code example to demonstrate it's embeddedness ...in a macro...Richard
I know I'm not merging because, before merging this &new-data-set with another one, I want to add to it a new variable with the same value for each of them (to show the origin). I don't know if I need the do loop or not, because the value of the observation dos not depend of the row, I want the same value for each observation in my new variable.videorama17
And I know that "my code isn't working" isn't good enough but if I knew what was wrong I would probably fix it. Right now I only have a log message about the whole macro (which was working before I added this piece), saying that the macro definition was not terminated before end of file (which I don't understand because I don't think I missed a ; and I have a valid mend).videorama17

2 Answers

0
votes

Nothing seems to be wrong with the part of the code that creates the variables. There might be other issues that are difficult to tell from this extract without seeing the entire code or log. For example, if Nom_controle and Partenaire are meant to be character variables because the macro variables are characters but without quotes then there will definitely be errors. You should use symbolgen and mprint options and then post the log to help solve the problem.

0
votes

Run a single data step, setting the new variables to the values setup in macro variables. If the values setup are character in nature the data step variables need to resolve those macro variables within double quotes.

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

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

Note: The new data set variables lengths will be set to the length of the values stored in the macro variables.

A data set is a rectangle of values. It will have a certain number of rows and columns of numeric and / or character types. The SET statement in a DATA step reads one row of the table's column values into the running program data vector -- which are essentially the variables in the DATA step. A DATA step loops automatically and halts automatically on various conditions, such as the last row of a SET table being read.

I don't know why you have a macro loop %DO I=1 %TO 10. I might speculate you think you need to do this in order to 'update' 10 rows in &new_data_set.

What is it really doing ? Running the same code 10 times! Without macro the actual code run is akin to the following

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;
...

One additional concern is the code such as

    %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;

It appears you are grabbing the first 3, 4, or 6th letters of the data set name from a fully qualified libname.dataset where libname is presumed to be sasuser. A safer and more robust version could be

%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,_);