I have a list of ranges, data looks like this:
Enteral Formulas and Additives | B4100-B4162 | B4100 | B4162 |
Parenteral Solutions and Supplies | B4164-B5200 | B4164 | B5200 |
Nutrition Infusion Pumps and Supplies Not Otherwise Classified | B9002-B9999 | B9002 | B9999 |
Other Theraputic Procedures | C1052-C1062 | C1052 | C1062 |
Outpatient PPS | C1713-C9899 | C1713 | C9899 |
Walking Aids and Attachments | E0100-E0159 | E0100 | E0159 |
Sitz Bath/Equipment | E0160-E0162 | E0160 | E0162 |
Commode Chair and Supplies | E0163-E0175 | E0163 | E0175 |
I need to turn it into a list that includes all the values in between, single column, something like to include every value in every range:
B9002 |
B9003 |
B9004 |
B9005 |
C1052 |
C1053 |
C1054 |
C1055 |
C1056 |
C1057 |
C1058 |
C1059 |
C1060 |
C1061 |
C1062 |
E0100 |
E0101 |
E0102 |
My thought was create a list with all the values A0001-A9999, B0001-B9999, etc for every letter of the alphabet then compare it back to my range list and only keep those that fall within one of the ranges. I was thinking a nested loop, the outside loop increments for the letter (runs 26 times), the inside loop increments for the numbers (runs 9999 times for each letter). I can figure out a loop to create the values 0001-9999 but I can't figure out how to increment the letter.
I've tried converting the letter to ascii, hex, octal, so I can increment it as a number, can't get any of that to work (example below). It runs but it's not doing anything useful with the letter..the result is the same with ascii, hex, and octal.
data Proc_List;
ltr = 'A';
put ltr $ascii3.;
do i = 1 to 9999 by 1;
Proc = cat(ltr, put(i, z4.)); /* values are 1, 2.25, 4, ..., 16, 20.25, 25 */
output;
end;
run;
Any ideas?
Why does your output show B9002 to B9005, and not any other values starting with B?
My first question is why?
If you're trying to merge with a different table you can make the condition dynamic to search between two strings?
Otherwise:
data want;
set have;
start = input(compress(startCode, , 'kd'), 8.); /*1*/
end = input(compress(endCode, , 'kd'), 8.); /*1*/
prefix = substr(startCode, 1, 1); /*2*/
do i=start to end; /*3*/
code = catt(prefix, put(i, z4.));
output; /*4*/
end;
run;
@TXHHS wrote:
I have a list of ranges, data looks like this:
Enteral Formulas and Additives B4100-B4162 B4100 B4162 Parenteral Solutions and Supplies B4164-B5200 B4164 B5200 Nutrition Infusion Pumps and Supplies Not Otherwise Classified B9002-B9999 B9002 B9999 Other Theraputic Procedures C1052-C1062 C1052 C1062 Outpatient PPS C1713-C9899 C1713 C9899 Walking Aids and Attachments E0100-E0159 E0100 E0159 Sitz Bath/Equipment E0160-E0162 E0160 E0162 Commode Chair and Supplies E0163-E0175 E0163 E0175
I need to turn it into a list that includes all the values in between, single column, something like to include every value in every range:
B9002 B9003 B9004 B9005 C1052 C1053 C1054 C1055 C1056 C1057 C1058 C1059 C1060 C1061 C1062 E0100 E0101 E0102
My thought was create a list with all the values A0001-A9999, B0001-B9999, etc for every letter of the alphabet then compare it back to my range list and only keep those that fall within one of the ranges. I was thinking a nested loop, the outside loop increments for the letter (runs 26 times), the inside loop increments for the numbers (runs 9999 times for each letter). I can figure out a loop to create the values 0001-9999 but I can't figure out how to increment the letter.
I've tried converting the letter to ascii, hex, octal, so I can increment it as a number, can't get any of that to work (example below). It runs but it's not doing anything useful with the letter..the result is the same with ascii, hex, and octal.
data Proc_List;
ltr = 'A';
put ltr $ascii3.;
do i = 1 to 9999 by 1;
Proc = cat(ltr, put(i, z4.)); /* values are 1, 2.25, 4, ..., 16, 20.25, 25 */
output;
end;
run;
Any ideas?
You could hack SAS name list generation feature :
data have;
length name $100 range $16;
input name & range;
datalines;
Enteral Formulas and Additives B4100-B4162 B4100 B4162
Parenteral Solutions and Supplies B4164-B5200 B4164 B5200
Nutrition Infusion Pumps and Supplies Not Otherwise Classified B9002-B9009 B9002 B9009
Other Theraputic Procedures C1052-C1062 C1052 C1062
Outpatient PPS C1713-C1719 C1713 C1719
Walking Aids and Attachments E0100-E0159 E0100 E0159
Sitz Bath/Equipment E0160-E0162 E0160 E0162
Commode Chair and Supplies E0163-E0175 E0163 E0175
;
filename arrays temp;
data _null_;
file arrays;
set have;
arrayName = cats("x", _n_);
str = catx(" ", "array", arrayName, "{*}", range, ";");
put str;
run;
data want(keep=name);
%include arrays;
array all _numeric_;
do i = 1 to dim(all);
name = vname(all{i});
output;
end;
run;
Why? All of the possible numeric suffixes in those ranges will include codes that are not valid HCPCS codes.
Just merge the list with a list of valid codes and pick the ones that fall between the two codes.
Let's assume the table you are showing is named HAVE and last two variables are named LOW and HIGH. So if your dictionary table of all valid codes is named HCPCS then just join them:
proc sql;
create table want as
select a.*,b.code
from have a
left join hcpcs b
on b.code between a.low and a.high
;
quit;
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 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.