Hi,
I have the following dataset:
Obs | ID | A | B | C |
1 | 1 | 1 | . | . |
2 | 1 | . | 1 | . |
3 | 1 | 1 | . | . |
How do I make SAS look through columns A, B and C for each observation, to return a table as below:
Obs | ID | A | B | C | Category |
1 | 1 | 1 | . | . | A |
2 | 1 | . | 1 | . | B |
3 | 1 | 1 | . | . | A |
Here, after a minor tweak,
data have;
input Obs ID A B C ;
cards;
1 1 1 . .
2 1 . 1 .
3 1 1 . 1
;
data want;
set have;
array _t a--c;
length category $ 100;
do over _t;
if _t=1 then category=catx('-',category,vname(_t));
/*category=vname(_t(whichn(1,of _t(*))));*/
end;
run;
Let's clarify the problem a little. Are you looking for the "first" variable of A B or C with ANY value or specifically the first with a value of 1?
What do you want for output if all of the values are missing?
data have;
input id:$1. A B C;
cards;
1 1 . .
1 . 1 .
1 1 . .
;
run;
data want(drop=str key lastcat);
format key $8. category $1.;
if _n_ = 1 then do;
lastCat = 0;
declare hash lu();
lu.defineKey('key');
lu.defineData('category');
lu.defineDone();
end;
set have;
array vars {3} A B C;
str = 'ABCDFGHIJKLMNOPQRSTUVWXYZ';
key=catx(',',of vars{*});
if lu.find()=0 then output;
else do;
lastCat + 1;
category = substr(str,lastCat,1);
lu.add();
output;
end;
run;
The question of what the category value should be is a little tricky. If it has to be a letter, then this code will work for up to 26 categories.
It would be easiet if the category values were numbers, in which case you would just change category = lastCat instead of substr(), and remove the str variable creation.
The following code choose the first '1' if you have multiple, tweak it to accomodate your real data:
data have;
input Obs ID A B C ;
cards;
1 1 1 . .
2 1 . 1 .
3 1 1 . .
;
data want;
set have;
array _t a--c;
length category $ 10;
category=vname(_t(whichn(1,of _t(*))));
run;
Here, after a minor tweak,
data have;
input Obs ID A B C ;
cards;
1 1 1 . .
2 1 . 1 .
3 1 1 . 1
;
data want;
set have;
array _t a--c;
length category $ 100;
do over _t;
if _t=1 then category=catx('-',category,vname(_t));
/*category=vname(_t(whichn(1,of _t(*))));*/
end;
run;
data have;
input
id:$1.
M01 : 1.
M02 : 1.
L01 : 1.;
cards;
A 1 . .
B 1 . 1
C 1 . .
D . 1 1
E 1 . 1
;
run;
data want(drop=key lastcat);
format key $60.;
if _n_ = 1 then do;
lastCat = 0;
declare hash lu();
lu.defineKey('key');
lu.defineData('category');
lu.defineDone();
end;
set have;
array vars {3} M01 -- L01;
key=catQ('a',',',of vars{*});
if lu.find()=0 then output;
else do;
lastCat +1;
category = lastCat;
lu.add();
output;
end;
run;
Ok, I think this is what you're describing.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.