0
votes

I would like to create a variable called DATFL that would have the following values for the last obseration :

DATFL
gender/scan

Here is the code :

data mix_ ;
input id $  name $  gender $  scan $;
datalines;
1 jon   M  F
2 jill  F  L
3 james F  M
4 jonas M  M
;
run;

data mix_3; set mix_; 
length datfl datfl_ $ 50;
array m4(*) id name gender scan;
retain datfl;
 do i=1 to dim(m4);
  if index(m4(i) ,'M') then do; 
    datfl_=vname(m4(i)) ;
    if missing(datfl) then datfl=datfl_;
    else datfl=strip(datfl)||"/"||datfl_;
  end;
 end;

run;

Unfortunately, the value I get for 'DATFL' at the last observation is 'gender/scan/gender/scan'.Obviously because of the retain statement that I used for 'DATFL' I ended up with duplicates. At the end of this data step, I was planning to use a CALL SYMPUT statement to load the last value into macro variable but I won't do it until I fix my issue...Can anyone provide me with a guidance on how to prevent 'DATFL' to have duplicates value at the end of the dataset ? Cheers sas_kappel

3
Sorry guys, the title does not exactly reflect the nature of my problem...sas_kappel
I'm confused. Can you post what you expect the output to be.Reeza

3 Answers

0
votes

Don't retain DATFL, Instead, retain DATFL_.

data mix_3; set mix_; 
    length datfl datfl_ $ 50;
    array m4(*) id name gender scan;
    retain datfl_;
    do i=1 to dim(m4);
        if index(m4(i) ,'M') then do; 
            datfl_=vname(m4(i)) ;
            if missing(datfl) then datfl=datfl_;
            else datfl=strip(datfl)||"/"||datfl_;
        end;
    end;
    if missing(datfl) then datfl = datfl_;

run;
0
votes

It doesn't work...Let me change the dataset (mix_) and you can see that RETAIN DATFLl_, is not working in this scenario.

data mix_ ;
 input id $  name $  gender $  scan $;
 datalines;
1 jon   M  M
2 Marc  F  L
3 james F  M
4 jonas H  M
;
run;

To resume, what I want is to have the DISTINCT value of DATFL, into a macro variable. The code that I proposed does,for each records,a search for variables having the letter M, if it true then DATFL receives the variable name of the array variable. If there are multiple variable names then they will be separated by '/'. For the next records, do the same, BUT add only variable names satisfying the condition AND the variables that were not already kept in DATFL. Currently, if you run my program I have for DATFL at observation 4, DATFL=gender/scan/name/scan/scan but I would like to have DATFL=gender/scan/name , because those one are the distinct values. Ultimatlly, I will then write the following code;

if eof then CALL SYMPUT('DATFL',datfl);

sas_kappel

0
votes

Your revised data makes it much clearer what you're looking for. Here is some code that should give the correct result.
I've used the CALL CATX function to add new values to DATFL, separated by a /. It first checks that the relevant variable name doesn't already exist in the string.

data mix_ ;
 input id $  name $  gender $  scan $;
 datalines;
1 jon   M  M
2 Marc  F  L
3 james F  M
4 jonas H  M
;
run;

data _null_;
set mix_ end=eof;
length datfl $100; /*or whatever*/
retain datfl;
array m4{*} $ id name gender scan;
do i = 1 to dim(m4);
if index(m4{i},'M') and not index(datfl,vname(m4{i})) then call catx('/',datfl,vname(m4{i}));
end;
if eof then call symput('DATFL', datfl);
run;

%put datfl = &DATFL.;