BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Sathish_jammy
Lapis Lazuli | Level 10

Hi Community,

 

Just consider the dataset as an example. 

w - wood; p- plastic ; s - steel  ; Items 1 2 3 4 5....(wooditem1 w1; plasticitem5 p5; steelitem3 s3 and so on)....

Here these 3 stuffs have a value. I want to sum up the value by category.

 

data xxx;
input aa$ bb$ cc$ dd$ c1 c2 c3 c4;
cards;
w1 p2 s4 w3 10 45 14 5
s1 s3 w2 p4 20 14 15 84
p2 w4 w5 w4 12 18 45 7
s1 w3 p5 s2 23 56 87 44
run;
proc print data = xxx;
run;

This is how my output should be as a result

 

 

WSP
151445
341584
12070

Could any one suggest some code by SAS or Proc SQL to resolve it.

Thanks in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User
data xxx;
input aa$ bb$ cc$ dd$ c1 c2 c3 c4;
cards;
w1 p2 s4 w3 10 45 14 5
s1 s3 w2 p4 20 14 15 84
p2 w4 w5 w4 12 18 45 7
s1 w3 p5 s2 23 56 87 44
;
run;

data want;
 set xxx;
 w=0;p=0;s=0;
 array x{*} $ aa bb cc dd;
 array y{*} c1-c4;
 do i=1 to dim(x);
   if x{i}=: 'w' then w+y{i};
    else if x{i}=: 'p' then p+y{i};
     else if x{i}=: 's' then s+y{i};
 end;
 keep w p s;
run;

View solution in original post

4 REPLIES 4
Andy_D
Fluorite | Level 6

Try below code:

 

%let name_list =aa bb cc dd;

%macro loop();

	data xxx2;
		set xxx;

		w = 0;
		s = 0;
		p = 0;

		%let i=1;
		%do %while (%scan(&name_list, &i) ne );

   			%let next_name = %scan(&name_list, &i);
			if substr(&next_name.,1,1) = 'w' then w = w + c&i.;
			else if substr(&next_name.,1,1) = 's' then s = s + c&i.;
			else if substr(&next_name.,1,1) = 'p' then p = p + c&i.;
   			%let i = %eval(&i + 1);

		%end;

	run;

%mend;

%loop();

 

If the variables your using to identify each material are easy to loop through (i.e. mat1,mat2,mat3.......) then the above can be simplified.

 

Regards,

Andy

Sathish_jammy
Lapis Lazuli | Level 10

Thank you! @Andy_D @Ksharp

Your code works well.

Ksharp
Super User
data xxx;
input aa$ bb$ cc$ dd$ c1 c2 c3 c4;
cards;
w1 p2 s4 w3 10 45 14 5
s1 s3 w2 p4 20 14 15 84
p2 w4 w5 w4 12 18 45 7
s1 w3 p5 s2 23 56 87 44
;
run;

data want;
 set xxx;
 w=0;p=0;s=0;
 array x{*} $ aa bb cc dd;
 array y{*} c1-c4;
 do i=1 to dim(x);
   if x{i}=: 'w' then w+y{i};
    else if x{i}=: 'p' then p+y{i};
     else if x{i}=: 's' then s+y{i};
 end;
 keep w p s;
run;
hashman
Ammonite | Level 13

Note that in the rows 2-3 of your proposed output the values of W and S are swapped. Assuming that it's a typo, you've already been offered a solution. One problem with it is that the output variables W, S, P are hard coded. It's fine when you know that is all you have. But in the real world with the data structured like yours - when the information about output metadata is embedded into the data, the aggregate variable names cannot be determined without a preliminary pass through the input: Doing otherwise would mean making assumption about the data.

 

One way of avoiding this rather precarious practice is to analyze the input data set first by reading it in full, find out what the distinct prefixes in the values of the variables aa--dd are and then hard code them into a conditional structure, such as if-then-else. Another, more dynamic, approach is to let SAS do the job as shown below. This way, you don't care what the prefixes are: They are discovered in the first pass, and in the ensuing aggregating pass, the compiler knows the output variable names and types automatically.

 

data have ;                                                    
  input aa$ bb$ cc$ dd$ c1 c2 c3 c4 ;                          
  cards ;                                                      
w1 p2 s4 w3 10 45 14  5                                        
s1 s3 w2 p4 20 14 15 84                                        
p2 w4 w5 w4 12 18 45  7                                        
s1 w3 p5 s2 23 56 87 44                                        
run ;                                                          
/* 1st pass: Find output vnames for 2nd pass */                
data _null_ ;                                                  
  do until (z) ;                                               
    set have end = z ;                                         
    array ch _char_ ;                                          
    length vv $ 32767 ;                                        
    do over ch ;                                               
      v = compress (ch, , "d") ;                               
      if not findw (vv, cats (v)) then vv = catx (" ", vv, v) ;
    end ;                                                      
  end ;                                                        
  call symputx ("vv", vv) ;                                    
run ;                                                          
/* 2nd pass: Aggregate into var list &vv */                    
data want (keep = &vv) ;                                       
  set have ;                                                   
  array ch _char_ ;                                            
  array nn _numeric_ ;                                         
  array vv (j) &vv ;                                           
  do over vv ;   
vv = 0 ; do over ch ; if ch =: vname (vv) then vv = sum (vv, nn) ; end ; end ; run ;

 

The correct output will look as follows:

 

 W   P   S
----------
15  45  14
15  84  34
70  12   0
56  87  67

Paul D.

  

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 4 replies
  • 798 views
  • 3 likes
  • 4 in conversation