OK. Assuming I understand what you mean.
DATA want_1;
INPUT var1 $ var2 $;
DATALINES;
10101 0
10101 100000
0 10100
10101 0
;
RUN;
data want;
set want_1;
array v{2} $ var1 var2 ;
array v1{3} $ 2 var11-var13 ;
array v2{3} $ 2 var21-var23 ;
length temp $ 6;
do i=1 to dim(v);
temp=v{i};
temp=translate(right(temp),'0',' ');
v{i}=temp;
if i=1 then do;
k=0;
do j=1 to 6 by 2;
k+1;
v1{k}=substr(v{i},j);
end;
end;
if i=2 then do;
k=0;
do j=1 to 6 by 2;
k+1;
v2{k}=substr(v{i},j);
end;
end;
end;
drop temp i j k;
run;
@Ksharp Thank you for your time and effort here. This code works great, but I should have been more clear. I have 53 variables. My example only included 2 variables. I was just trying to simplify things. The solution you proposed would require creating 53 arrays, correct?
I was hoping I could simply add a leading 0 to the character strings, so that I could use the code/approach I have been using for the other time periods/data sets.
Here is the array I am using already, for all the other datasets, that already have a leading 0 in front of the character strings:
DATA want; * Setting the length of the variables to be 6 characters long; LENGTH _400201 _400202 _400203 _400204 _400205 _400206 _400207 _400208 _400209 _400210 ... Up to 53 variables $6; SET have; ARRAY original {53} _400201 _400202 _400203 _400204 _400205 _400206 _400207 _400208 _400209 _400210 ... Up to 53 variables ; ARRAY new {53,3} $ 2 _400201_part1 - _400201_part3 _400202_part1 - _400202_part3 _400203_part1 - _400203_part3 _400204_part1 - _400204_part3 _400205_part1 - _400205_part3 _400206_part1 - _400206_part3 _400207_part1 - _400207_part3 _400208_part1 - _400208_part3 _400209_part1 - _400209_part3 _400210_part1 - _400210_part3 ...
Up to 53 variables ; DO i=1 to 53; DO j=1 to 3; new{i,j} = substr(original{i}, 2*j-1); END; END; DROP i j; RUN;
Any other ideas would be greatly appreciated.
OK. I would use proc transpose.
DATA want_1;
INPUT var1 $ var2 $;
DATALINES;
10101 0
10101 100000
0 10100
10101 0
;
RUN;
data temp;
set want_1;
array v{*} $ var1-var2 ;
length temp $ 6 vname $ 40 value $ 2;
n+1;
do i=1 to dim(v);
temp=v{i};
temp=translate(right(temp),'0',' ');
vname=vname(v{i});
k=0;
do j=1 to 6 by 2;
k+1;
value=substr(temp,j,2);
output;
end;
end;
drop i j ;
run;
proc transpose data=temp out=want(drop=_name_);
by n ;
var value;
id vname k;
run;
data want;
merge want_1 want;
run;
@Ksharp Thank you again. We are getting there!
3 questions/issues:
1. The character strings in the original variable are of differing lengths. Ideally, the character string is 6 character long, after the leading 0 is added. So, 400203=10101 would become 010101, which would then become 400203_part1=01, 400203_part2=01, 400203_part3_01. This syntax does that! However, if the string is a different length, like 100, for example. The resutls are as follows.
400201 |
_4002011 |
__4002012 |
_4002013 |
100 |
00 |
01 |
00 |
It should be:
400201 |
_4002011 |
__4002012 |
_4002013 |
100 |
01 |
00 |
00 or missing |
2. The other problem is w/ a value of 101 (i.e. Refused to respond). The results are as follows:
400203 |
_4002031 |
__4002032 |
_4002033 |
101 |
00 |
01 |
01 |
Here, the 3 resulting variables should probably be sett to missing ("").
3. Where in this syntax can I change the vew variable names? I can't quite figure it out. It would be ideal, to sync w/ the code that follows it, if the names could be _400201_part1, _400201_part2 _400201_part3 as opposed to _4002011, _4002012, _4002013.
Thank you again!!
So you don't want padding zero before it all the time ?
DATA want_1;
INPUT var1 $ var2 $;
DATALINES;
10101 0
10101 100000
0 10100
10101 0
100 101
;
RUN;
data temp;
set want_1;
array v{*} $ var1-var2 ;
length temp $ 6 vname $ 40 value $ 2 kname $ 40;
n+1;
do i=1 to dim(v);
temp=v{i};
if temp not in ('100' '101') then temp=translate(right(temp),'0',' ');
else if temp='100' then temp=translate(temp,'0',' ');
else if temp='101' then call missing(temp);
vname=vname(v{i});
k=0;
do j=1 to 6 by 2;
k+1;
kname=cats('Part',k);
value=substr(temp,j,2);
output;
end;
end;
drop i j ;
run;
proc transpose data=temp out=want(drop=_name_) delimiter=_;
by n ;
var value;
id vname kname;
run;
data want;
merge want_1 want;
run;
<So you don't want padding zero before it all the time ?>
I want the padding zero for all values except 101. With a value of 101, I want the subsequent variables to have missing values. This new code does that, but 100 still looks like this:
400201 |
_4002011 |
__4002012 |
_4002013 |
100 |
00 |
01 |
00 |
It should be:
400201 |
_4002011 |
__4002012 |
_4002013 |
100 |
01 |
00 |
00 or missing
|
There are other combinations besides the character strings I included in the DATALINES statement (e.g. 10000). I apologize for not being more clear at the beginning.
DATA want_1; INPUT var1 $ var2 $; DATALINES; 10101 0 10101 100000 0 10100 10101 0 100 101 ; RUN; data temp; set want_1; array v{*} $ var1-var2 ; length temp $ 6 vname $ 40 value $ 2 kname $ 40; n+1; do i=1 to dim(v); temp=v{i}; if temp not in ('100' '101') then temp=translate(right(temp),'0',' '); else if temp='100' then temp='0'||temp; /*<----*/ else if temp='101' then call missing(temp); vname=vname(v{i}); k=0; do j=1 to 6 by 2; k+1; kname=cats('Part',k); value=substr(temp,j,2); output; end; end; drop i j ; run; proc transpose data=temp out=want(drop=_name_) delimiter=_; by n ; var value; id vname kname; run; data want; merge want_1 want; run;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.