BookmarkSubscribeRSS Feed
cash_moonshine
Fluorite | Level 6
1  data lib.new_data (keep = red: green: blue: yellow:
2! qual_pr qual_pr_pos i10_pr1-i10_pr31
3      set lib.old_data
4     array proc_cd_{*} i10_pr1-i10_pr31;
5
6      red=0;
7      green=0;
8     blue=0;
9      yellow=0;
10
11  do i=1 to 31;
12             if put(proc_cd_{i}, $source.)= "Red" then do;
13                              red=1;
14                              red_qual_pr=proc_cd_{i};
15                              red_qual_pr_pos=(i);
16              end;
17  end;
18  do i=1 to 31;
19              if put(proc_cd_{i}, $source.)= "Green" then do;
20                              green=1;
21                              green_qual_pr=proc_cd_{i};
22                              green_qual_pr_pos=(i);
23              end;
24  end;
25  do i=1 to 31;
26              if put(proc_cd_{i}, $source.)= "Blue" then do;
27                              blue=1;
28                              blue_qual_pr=proc_cd_{i};
29                              blue_qual_pr_pos=(i);
30              end;
31  end;
32  do i=1 to 31;
33             if put(proc_cd_{i}, $source.)= "Yellow" then do;
34                              Yellow=1;
35                              yellow_qual_pr=proc_cd_{i};
36                              yellow_qual_pr_pos=(i);
37              end;
38  end;
39      output;
40
41  run;

WARNING: The variable qual_pr in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable qual_pr_pos in the DROP, KEEP, or RENAME list has never been referenced.

This is what I get.

ballardw
Super User

This warning:

WARNING: The variable qual_pr in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable qual_pr_pos in the DROP, KEEP, or RENAME list has never been referenced.

occurs when you use a variable name some where in the code but never assign values or use in any calculations.

In this particular case it is probably the KEEP option in the Data statement:

1  data lib.new_data (keep = red: green: blue: yellow:
2! qual_pr qual_pr_pos i10_pr1-i10_pr31

Which may have been truncated when copying because there is no closing ) for the Keep option or ;

Your keep references Qual_pr and Qual_pr_pos.

The body of your code uses variable names like Red_qual_pr. So since those are not on the keep they get dropped and the variables Qual_pr and Qual_pr_pos are created because you told SAS to keep them. But they never had values assigned, only the Red_ Yellow_ Green_ and Blue_ versions had values (maybe).

Reeza
Super User
So far we've seen code that doesn't work and data that doesn't give you what you want. I'm still waiting to see what you want from more than two variables.
cash_moonshine
Fluorite | Level 6

Essentially, each row is a patient who could have any number of the 31 I10_PR codes. I have imported a data set and created a format from it; this data set is a list of ICD10 codes and a label: Red, Blue, Green, or Yellow. What I want is for the do loop to go through the second, patient data set and if any PR code is present for that patient, give a value of 1 to Red, Green, Blue, or Yellow depending on if that code is associated with any of those color labels.

So if there is a PR code present while the do loop for Red is running, it should give a value of 1 to red when it sees the code and the $source_color label from the format that I created.

Instead, it skips Red, leaves it as 0, and give Green a value of 1 when the Green do loop is running.

I need it to give values of 1 to each color label any time a code is present for one of those labels.

Ultimately, I need to know which color label is contributing the most codes to the final patient data set.

Kurt_Bremser
Super User

So your initial problem is bad dataset structure. With a long dataset, the code is fairly simple:

data code_data;
input code $ source_colors $;
datalines;
0DBC0ZZ Red
0DBE0ZZ Red
0DBC0ZZ Green
0DBE0ZZ Green
0DBC0ZZ Blue
0DBE0ZZ Blue
0DBC0ZZ Yellow
0DBE0ZZ Yellow
;

data old_data;
input patid $ I10_PR1 $ I10_PR2 $ I10_PR3 $;
datalines;
A 0DBC0ZZ 0BQS0ZZ 0BQR4ZZ
B 0DBE0ZZ 07BP4ZZ 0BQT0ZZ
C 0DBC0ZZ 0BQS0ZZ 0BQR4ZZ
D 0DBE0ZZ 07BP4ZZ 0BQT0ZZ
E 0DBC0ZZ 0BQS0ZZ 0BQR4ZZ
F 0DBE0ZZ 07BP4ZZ 0BQT0ZZ
G 0DBC0ZZ 0BQS0ZZ 0BQR4ZZ
H 0DBE0ZZ 07BP4ZZ 0BQT0ZZ
;

proc transpose
  data=old_data
  out=long (drop=_name_ rename=(col1=code))
;
by patid;
var I10:;
run;

proc sql;
create table want_long as
  select distinct
    l.patid,
    c.source_colors,
    1 as value
  from long l inner join code_data c
  on l.code = c.code
;
quit;

proc transpose
  data=want_long
  out=want (drop=_name_)
;
by patid;
id source_colors;
var value;
run;

 

ballardw
Super User

@cash_moonshine wrote:

Essentially, each row is a patient who could have any number of the 31 I10_PR codes. I have imported a data set and created a format from it; this data set is a list of ICD10 codes and a label: Red, Blue, Green, or Yellow. What I want is for the do loop to go through the second, patient data set and if any PR code is present for that patient, give a value of 1 to Red, Green, Blue, or Yellow depending on if that code is associated with any of those color labels.

So if there is a PR code present while the do loop for Red is running, it should give a value of 1 to red when it sees the code and the $source_color label from the format that I created.

Instead, it skips Red, leaves it as 0, and give Green a value of 1 when the Green do loop is running.

I need it to give values of 1 to each color label any time a code is present for one of those labels.

Ultimately, I need to know which color label is contributing the most codes to the final patient data set.


I have worked occasionally with ICD-10 and ICD-9 codes before that. Your presentation of values is so far off what I have seen, including multiple questions on the forum with different "coding" for ICD values that it never occurred to me that they might be ICD codes at all.

cash_moonshine
Fluorite | Level 6

Sorry, didn't see your edited message. I've tried to expand the data:

data old_data;
   input I10_PR1 $ I10_PR2 $ I10_PR3 $;
   datalines;
0DBC0ZZ 0BQS0ZZ 0BQR4ZZ
0DBE0ZZ 07BP4ZZ 0BQT0ZZ
0DBC0ZZ 0BQS0ZZ 0BQR4ZZ
0DBE0ZZ 07BP4ZZ 0BQT0ZZ
0DBC0ZZ 0BQS0ZZ 0BQR4ZZ
0DBE0ZZ 07BP4ZZ 0BQT0ZZ
0DBC0ZZ 0BQS0ZZ 0BQR4ZZ
0DBE0ZZ 07BP4ZZ 0BQT0ZZ
;
Tom
Super User Tom
Super User

I think I know what you are trying to do.  You have a multiple codes per observations.  You have multiple classifications categories (COLORS).  You want to calculate for each observation a  flag for each category to say whether or not any code from that category appears.  

 

Your sample codes are impossible for humans to easily distinguish.  So let's convert them to  something easier to eyeball quickly.  Also it looks all of your example test data have codes from every possible category.  So let's make some new test data.

data old_data;
  id+1;
  input I10_PR1 $ I10_PR2 $ I10_PR3 $;
datalines;
AAA BBB CCC 
DDD EEE FFF
GGG HHH III
;

data codes;
   input code $ color $;
   datalines;
AAA Red
AAA Blue
BBB Red
CCC Green
DDD Green
EEE Blue
FFF Blue
GGG Yellow
HHH Yellow
;

In this test data only the code AAA maps to more than one category.

 

So first let's convert your code/category mapping into multiple informats that will return 1 when the code is in the category.  As long as the category names (colors) are valid informat names this is easy.  If they aren't just make up some names for the informats.

proc sort data=codes out=cntlin; by color code ; run;

data cntlin;
  set cntlin;
  type='I';
  rename color=fmtname;
  label=1;
  rename code=start;
run;

proc format cntlin=cntlin; 
run;

First let's get the list of categories so we can use them to make the names of the new variables.

proc sql noprint;
  select distinct color into :clist separated by ' ' from codes;
quit;

Now let's use the informats to categorize the codes. 

data want;
  set old_data;
  array flags &clist ;
  array in I10_PR: ;
  do color=1 to dim(flags);
    flags[color]=0;
  end;
  do code=1 to dim(in) until(1=min(of flags[*]));
    do color=1 to dim(flags);
      if inputn(in[code],vname(flags[color])) then flags[color]=1;
    end;
  end;
  drop code color ;
run;

Results:

Obs    id    I10_PR1    I10_PR2    I10_PR3    Blue    Green    Red    Yellow

 1      1      AAA        BBB        CCC        1       1       1        0
 2      2      DDD        EEE        FFF        1       1       0        0
 3      3      GGG        HHH        III        0       0       0        1

Reeza
Super User

@Tom wrote:

I think I know what you are trying to do. 


If this were true, I think a solution I posted a while back would have worked.  

I highly suspect OP has neglected to mention one complexity, multiple records per person that s/he also wants consolidated.

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 23 replies
  • 1312 views
  • 6 likes
  • 6 in conversation