/* Chapter 12: Mixed Solutions */

/* Jump to: Chapter 11    Table of Contents    Chapter 13 */

/*

*/

/* 12.1: Example: Schedule Matrix */

/* Jump to: Next Section */

DATA Arrivals;                                                                  
INPUT Name $ Arrival   : TIME5.;                                                
FORMAT       Arrival     TIME5.;                                                
CARDS;                                                                          
John   14:30                                                                    
Paul   15:00                                                                    
Ringo  15:30                                                                    
George 16:00                                                                    
;                                                                               
                                                                                
DATA Departures;                                                                
INPUT Name $ Departure : TIME5.;                                                
FORMAT       Departure   TIME5.;                                                
CARDS;                                                                          
John   15:30                                                                    
Paul   16:00                                                                    
Ringo  17:30                                                                    
George 18:00                                                                    
;                                                                               
                                                                                
PROC SQL;                                                                       
SELECT       *                                                                  
FROM         Arrivals                                                           
             CROSS JOIN                                                         
             Departures                                                         
;                                                                               
QUIT;                                                                           
                                                                                
PROC SQL;                                                                       
CREATE VIEW  Pairs AS                                                           
SELECT         CASE WHEN arr.name > dep.name                                    
                    THEN arr.name                                               
                    ELSE dep.name                                               
                    END AS UpDown_Name                                          
             , CASE WHEN arr.name > dep.name                                    
                    THEN dep.name                                               
                    ELSE arr.name                                               
                    END AS Across_Name                                          
             , MAX(arrival)   AS LoTime FORMAT=TIME5.                           
             , MIN(departure) AS HiTime FORMAT=TIME5.                           
FROM         Arrivals   AS arr                                                  
             CROSS JOIN                                                         
             Departures AS dep                                                  
GROUP BY     UpDown_Name, Across_Name                                           
ORDER BY     UpDown_Name, Across_Name                                           
;                                                                               
QUIT;                                                                           
                                                                                
DATA _NULL_;                                                                    
FILE PRINT N=PS;                                                                
SET Pairs;                                                                      
BY updown_name;                                                                 
IF FIRST.updown_name THEN DO;                                                   
   updown + 1;                                                                  
   across = 0;                                                                  
   END;                                                                         
across + 1;                                                                     
IF updown_name=across_name THEN                                                 
     PUT # 2 'Individual Presence'                                              
         # 4 @(13*across) across_name $13.-R                                    
         # 6 @;                                                                 
ELSE PUT # 8 'Joint Presence'                                                   
         #10 @(13*across) across_name $13.-R                                    
         #(updown+10) @1 updown_name @;                                         
PUT          @(13*across) +3 @;                                                 
IF HiTime > LoTime THEN                                                         
     PUT LoTime +(-1) '-' HiTime;                                               
ELSE PUT '. . . . . .';                                                         
RUN;                                                                            

/* Jump to: Top of Section     Top of Chapter */

/* 12.2: Example: Identifying Spikes in a Series */

/* Jump to: Next Section */

DATA Readings;                                                                  
DO _n_ = 1 to 10;                                                               
   Reading = FLOOR(100 * RANUNI(2468) ) / 10;                                   
   OUTPUT;                                                                      
   END;                                                                         
RUN;                                                                            
                                                                                
DATA Numbered;                                                                  
RowNum + 1;                                                                     
SET Readings;                                                                   
RUN;                                                                            
                                                                                
PROC SQL;                                                                       
CREATE TABLE flagged AS                                                         
SELECT       This.Reading,                                                      
             CASE WHEN N( Prev.Reading,                                         
                          This.Reading,                                         
                          Next.Reading ) < 3                                    
                  THEN ''                                                       
                  WHEN    This.Reading >                                        
                          Prev.Reading + 3 AND                                  
                          This.Reading >                                        
                          Next.Reading + 3                                      
                  THEN 'High'                                                   
                  WHEN    This.Reading <                                        
                          Prev.Reading - 3 AND                                  
                          This.Reading <                                        
                          Next.Reading - 3                                      
                  THEN 'Low'                                                    
                  ELSE ''                                                       
                  END AS Flag                                                   
FROM         Numbered AS This                                                   
             LEFT JOIN                                                          
             Numbered AS Prev                                                   
             ON (This.RowNum - 1) = Prev.RowNum                                 
             LEFT JOIN                                                          
             Numbered AS Next                                                   
             ON (This.RowNum + 1) = Next.RowNum                                 
;                                                                               
QUIT;                                                                           

/* Jump to: Top of Section     Top of Chapter */

/* 12.3: Example: Using PROC TRANSPOSE to Normalize */

/* Jump to: Next Section */

DATA wide;                                                                      
INPUT ID $ Estimated Net Gross Adjusted;                                        
CARDS;                                                                          
A 11 12 13 14                                                                   
B 21 22 23 24                                                                   
;                                                                               
                                                                                
PROC TRANSPOSE DATA=wide                                                        
 OUT=long(rename = (_name_=Item col1=Value) );                                  
BY ID;                                                                          
RUN;                                                                            
                                                                                
PROC SQL;                                                                       
SELECT       ID, 'Estimated' AS Item, Estimated AS Value                        
FROM         wide                                                               
;                                                                               
QUIT;                                                                           
                                                                                
PROC SQL;                                                                       
CREATE TABLE long AS                                                            
SELECT       ID, 'Estimated' AS Item, Estimated AS Value                        
FROM         wide                                                               
UNION ALL                                                                       
SELECT       ID, 'Net'              , Net                                       
FROM         wide                                                               
UNION ALL                                                                       
SELECT       ID, 'Gross'            , Gross                                     
FROM         wide                                                               
UNION ALL                                                                       
SELECT       ID, 'Adjusted'         , Adjusted                                  
FROM         wide                                                               
;                                                                               
QUIT;                                                                           
                                                                                
PROC SQL;                                                                       
CREATE TABLE verticalsums AS                                                    
SELECT       item, SUM(value) as Sum                                            
FROM         long                                                               
GROUP BY     item                                                               
;                                                                               
QUIT;                                                                           
                                                                                
PROC SQL;                                                                       
CREATE TABLE numbered AS                                                        
SELECT       id, varnum, item, value                                            
FROM         long                                                               
             INNER JOIN                                                         
             ( SELECT name, varnum                                              
               FROM   dictionary.columns                                        
               WHERE  libname='WORK' AND                                        
                      memname='WIDE'                                            
             )                                                                  
             ON       name=item                                                 
;                                                                               
QUIT;                                                                           
                                                                                
PROC SQL;                                                                       
CREATE TABLE verticalsums AS                                                    
SELECT       varnum, item, SUM(value) as Sum                                    
FROM         numbered                                                           
GROUP BY     varnum, item                                                       
ORDER BY     varnum                                                             
;                                                                               
QUIT;                                                                           
                                                                                
PROC TRANSPOSE DATA=verticalsums                                                
 OUT=horizontalsums(drop = _name_);                                             
ID item;                                                                        
VAR sum;                                                                        
RUN;                                                                            

/* Jump to: Top of Section     Top of Chapter */