Search code examples
saslookup-tables

SAS lookup tables to match data


I am trying to create a scoring table by looking up a grading system table. There are three teachers grade all the students, and they have their own way of grading. I am trying standardize students' marks by mapping to the look up table. My tables look like this:

 old grades table:
              prof_grade      TA_grade      chair_grade
  Anne           A+               A             AAA
  Peter          B+               B+            AA

  Look up table1:
             Score   Rating  Teacher
              10       A+      prof
              10       A        TA
              10      AAA      chair
               9       A       prof
               9       A-       TA
               9      AA       chair
               8      B+       prof
               8      B+        TA
               8      A        chair

  Look up table2:
             Prof    TA    chair
    10        A+      A     AAA
     9        A       A-     AA
     8        B+      B+      A

Two look up tables have the same contents, and I can use either table to be the mapping table.

I want my new table look like this

  new grades table:
         prof_grade   TA_grade   chair_grade   prof_score   TA_score chair_score
  Anne         A+       A           AAA          10           10          10
  Peter        B+       B+          AA            8            8           9

I know I can do this by multiple join, which would makes the code long and take me a long time to modify the code when more teachers are added in the look up table. Hence I want to find a more automated way without using join. I am thinking of using hash objects but the Rating in the look up table1 is not unique, unless it is combined with the Teacher column. Maybe I can use proc IML to solve this problem? Is there an easy way to create such table?


Solution

  • just use proc format, it is simple and straightforward.

        data have;
    input  name   $        prof_grade   $   TA_grade   $   chair_grade $;
    datalines;
    Anne           A+               A             A+
    Peter          B+               B+            AAA
    Pete           A+              A-            AA
    ;
    
    
    
     /* your lookup table for creating informats*/
      data lookup;
      input  Score   Rating  $  Teacher $;
     datalines;
          10       A+      prof
          10       A        TA
          10       AAA      chair
           9       A       prof
           9       A-       TA
           9       AA       chair
           8       B+       prof
           8       B+        TA
           8       A+       chair
       ;
    
      /* creating informat*/
     proc sql ;                               
     create table crfmt as                        
     select distinct 
         Teacher as fmtname, 
       strip(Rating) as start,          
       score as label,                   
       "J" as type
       from lookup;                        
     quit;    
    
    proc format library=work cntlin=crfmt fmtlib;
    run;
    
    
    /* using the informat created in the table above in first 2 cases score are 
    character values you need to use one more input change to number as shown below*/
    
     data want;
     set have;
     Prof_score = input(trim(prof_grade),$prof.);
     TA_score = input(trim(TA_grade),$TA.);
      /* to make it numeric value*/
      chair_score = input(input(trim(chair_grade),$chair.),best32.);
      run;
    

    Edit1: if you want to address for other values. please use the below code

       data have;
      input  name   $        prof_grade   $   TA_grade   $   chair_grade $;
      datalines;
      Anne           A+               A             A+
     Peter           B+               B+            AAA
     Pete            A+              A-            AA
     Smith          A+              A-            AAA1A
    ;
    
    
    
     /* your lookup table for creating informats*/
      data lookup;
     infile datalines missover;
      input  Score $  Rating  $  Teacher $;
     datalines;
      10       A+      prof
      10       A        TA
      10       AAA      chair
       9       A       prof
       9       A-       TA
       9       AA       chair
       8       B+       prof
       8       B+        TA
       8       A+       chair
       ;
    
      /* insert rows in lookup to address other values*/
        proc sql;
       insert into lookup   
      values(" ", "Unknown" ,   "chair");
      insert into lookup  
     values(" ", "Unknown" ,   "TA");
      insert into lookup
       values(" ", "Unknown" ,   "prof");
    
     /* creating informat*/
      proc sql ;                               
        create table crfmt as                        
       select distinct 
       Teacher as fmtname, 
       strip(Rating) as start,          
      score as label,                   
      "J" as type
      from lookup;                        
    quit;    
    
     proc format library=work cntlin=crfmt fmtlib;
     run;
    
    
    /* using the informat created in the table above in first 2 cases score are 
     character values you need to use one more input change to number as shown below*/
    
      data want;
        set have;
      if input(trim(prof_grade),$prof.) eq prof_grade
       then prod_score = ' ';
       else  prod_score = input(trim(prof_grade),$prof.);
      ;
       if input(trim(TA_grade),$TA.) eq TA_grade
       then TA_score = ' ';
        else  TA_score = input(trim(TA_grade),$TA.);
    
       if input(trim(Chair_grade),$chair.) eq Chair_grade
       then chair_score = ' ';
        else  chair_score = input(trim(chair_grade),$chair.);
       run;