BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Astana
Calcite | Level 5

Hello, SAS experts.

 

I have following data.

 

dategroupvalue
19910731123
19920731143
19930731154
19910731234
19920731223
19930731243
19910731323
19920731334
19930731323

 

I would like to add to this dataset group 4 with the values equals to the difference of values of group=1 and group=2 at the same date.

 

dategroupvalue
19910731123
19920731143
19930731154
19910731234
19920731223
19930731243
19910731323
19920731334
19930731323
19910731411
199207314-23
199307314-11

 

As the final output I would like to have a table with dates as rows and groups as columns. But the group 4 I would like to rename as "difference":

 

 Group 1Group 2Group 3Difference
1991073123342311
19920731432334-23
19930731544323-11

 

Could somebody help me with code.

1 ACCEPTED SOLUTION

Accepted Solutions
hashman
Ammonite | Level 13

@Astana:

If this is what you want, then try:

data have ;                            
  input date group value ;             
  cards ;                              
19910731 1 23                          
19920731 1 43                          
19930731 1 54                          
19910731 2 34                          
19920731 2 23                          
19930731 2 43                          
19910731 3 23                          
19920731 3 34                          
19930731 3 23                          
run ;                                  
                                       
data step1 ;                           
  do _n_ = 1 by 1 until (last.group) ; 
    set have ;                         
    by group ;                         
    output ;                           
    array v [3,3] _temporary_ ;        
    v[group,_n_] = value ;             
  end ;                                
  if group = 3 then do _n_ = 1 to _n_ ;
    set have (keep = date) ;           
    group = 4 ;                        
    value = v[2,_n_] - v[1,_n_] ;      
    output ;                           
  end ;                                
run ;                                  

Kind regards

Paul D. 

View solution in original post

8 REPLIES 8
Reeza
Super User
Transpose first to wide format (via PROC TRANSPOSE) and then the difference will be easier to calculate.
hashman
Ammonite | Level 13

@Astana:

Not sure what the value -23 for the difference is doing in your suggested output, as 23 - 43 = -20.

At any rate, assuming this is a typo, methinks the following should do it in one fell swoop and in the requisite output file format:

 

data have ;                                        
  input date group value ;                         
  cards ;                                          
19910731 1 23                                      
19920731 1 43                                      
19930731 1 54                                      
19910731 2 34                                      
19920731 2 23                                      
19930731 2 43                                      
19910731 3 23                                      
19920731 3 34                                      
19930731 3 23                                      
run ;                                              
                                                   
data want (drop=group) ;                           
  merge have (where=(group=1) rename=value=group1) 
        have (where=(group=2) rename=value=group2) 
        have (where=(group=3) rename=value=group3) 
  ;                                                
  by date ;                                        
  difference = group2 - group1 ;                   
run ;                                              

Note: BY DATE is included just in case you may have other (identically structured) records with different date values.

 

Kind regards

Paul D. 

Astana
Calcite | Level 5

Thank you for you answer.

But this advice misses one step. First I want to get the same data, just with one more group type added (group 4).

 

dategroupvalue
19910731123
19920731143
19930731154
19910731234
19920731223
19930731243
19910731323
19920731334
19930731323
19910731411
199207314-20
199307314-11
Ksharp
Super User

As Reeza said.

 

data have ;                                        
  input date group value ;                         
  cards ;                                          
19910731 1 23                                      
19920731 1 43                                      
19930731 1 54                                      
19910731 2 34                                      
19920731 2 23                                      
19930731 2 43                                      
19910731 3 23                                      
19920731 3 34                                      
19930731 3 23                                      
run ;            
proc sort data=have out=temp;
by date;
run;
proc transpose data=temp out=want prefix=group;
by date;
id group;
var value;
run; 
hashman
Ammonite | Level 13

@Ksharp:

Nice, as it internally automates the creation of group1, group2, etc.

But you need another step to compute group2-group1=difference. 

 

Kind regards

Paul D.

Astana
Calcite | Level 5

Thank you for you answer.

But this advice misses one step. First I want to get the same data, just with one more group type added (group 4).

 

dategroupvalue
19910731123
19920731143
19930731154
19910731234
19920731223
19930731243
19910731323
19920731334
19930731323
19910731411
199207314-20
199307314-11

 

hashman
Ammonite | Level 13

@Astana:

If this is what you want, then try:

data have ;                            
  input date group value ;             
  cards ;                              
19910731 1 23                          
19920731 1 43                          
19930731 1 54                          
19910731 2 34                          
19920731 2 23                          
19930731 2 43                          
19910731 3 23                          
19920731 3 34                          
19930731 3 23                          
run ;                                  
                                       
data step1 ;                           
  do _n_ = 1 by 1 until (last.group) ; 
    set have ;                         
    by group ;                         
    output ;                           
    array v [3,3] _temporary_ ;        
    v[group,_n_] = value ;             
  end ;                                
  if group = 3 then do _n_ = 1 to _n_ ;
    set have (keep = date) ;           
    group = 4 ;                        
    value = v[2,_n_] - v[1,_n_] ;      
    output ;                           
  end ;                                
run ;                                  

Kind regards

Paul D. 

Astana
Calcite | Level 5

Thank you! That is what I needed.

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 1931 views
  • 2 likes
  • 4 in conversation