Hello guys,
I am trying to convert a variable say "747.x" into 747.0,747.1,747.2---747.9 and place them in subsequent rows.
Like for example, my original dataset
Var |
747.x |
056.xx |
I want the dataset to look like
Converted |
747.0' |
747.1 |
747.2 |
747.3 |
747.4 |
747.5 |
747.6 |
747.7 |
747.8 |
747.9 |
056.00' |
056.01' |
056.02' |
. |
. |
056.99' |
I can use TRNWRD to replace .x with .0 or 0.1 etc but if there is an efficient way to convert .x into .0, 0.1...0.9 and place them into rows, that would be helpful!
Regards,
Tina
Like this?
data WANT;
set HAVE;
MAXNB=10**(length(scan(VAR,2)))-1;
do I=0 to MAXNB;
VAR=catt(scan(VAR,1),'.',putn(I,catt('z',length(cat(MAXNB)),'.')));
output;
end;
run;
VAR |
747.0 |
747.1 |
747.2 |
747.3 |
747.4 |
747.5 |
747.6 |
747.7 |
747.8 |
747.9 |
056.00 |
056.01 |
056.02 |
056.03 |
056.04 |
data have;
input Var $;
cards;
747.x
056.xx
;
data want;
set have;
_var=input(tranwrd(var, "x", "0"),8.);
_start=1/10**(length(scan(var,-1)));
_stop=1-_start;
want_var=_var;
output;
do _n=_start to _stop by _start;
want_var=_var+_n;
output;
end;
keep var want_var;
run;
Like this?
data WANT;
set HAVE;
MAXNB=10**(length(scan(VAR,2)))-1;
do I=0 to MAXNB;
VAR=catt(scan(VAR,1),'.',putn(I,catt('z',length(cat(MAXNB)),'.')));
output;
end;
run;
VAR |
747.0 |
747.1 |
747.2 |
747.3 |
747.4 |
747.5 |
747.6 |
747.7 |
747.8 |
747.9 |
056.00 |
056.01 |
056.02 |
056.03 |
056.04 |
See if this gets you started:
data want; length var $ 8; input var $; numx = countc(scan(var,2,'.'),'x'); if numx>0 then do i=0 to (10**numx - 1); select (numx); when (1) fmt='z1.'; when (2) fmt='z2.'; when (3) fmt='z3.'; otherwise; end; var = catx('.',scan(var,1,'.'),putn(i,fmt)); output; end; drop i numx fmt; datalines; 747.x 056.xx ; run;
This example will not work if you have a value like 123.1x, only if all the values after the decimal are x's. Considerations may be needed if the case of the x are inconsistent. I assumed lower case as per your example but adding a lowcase may be needed.
This will not replace X before the decimal if such occurs.
It will handle 3 x's if they appear.
Why go through that trouble? You can always locate the values you want using:
if ('747.' < varname < '748.');
I really appreciate all of your answers guys! I do have some values like 720.1x too; I found out a way to work with them using some macro coding but will try to understand the code here, and implement those for .1x type codes too. Will let you know how it goes. This is very helpful!
The same approach still works:
if ('720.1' < varname < '720.2');
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.