BookmarkSubscribeRSS Feed
ss171
Calcite | Level 5

Hi , Three is small help needed 

I have the below dataset 

data sample;
input name$ june july;
datalines ;
amount 170 140
account 2 4
;
run;

I need to create new row average which is amount/account 

output :

name junejuly
amount170140
account 24
average8535

 

 

 

 

 

10 REPLIES 10
rudfaden
Lapis Lazuli | Level 10

you can transpose it for a better structure. If you need it in the old form, you can transpose it back.

 

data sample;
input name$ june july;
datalines ;
amount 170 140
account 2 4
;
run;

proc transpose data=sample out=long;
id name;
run;

data want;
set long;
avg=amount/account;
rename _NAME_= Month;
run;
s_lassen
Meteorite | Level 14

You are probably better off with a transposed dataset (you may have some other identifying variables on the input data, which can be put in a BY statement):

proc transpose data=sample out=transposed(rename=(_name_=month));
  var june--july;
  id name;
run;

Then you can quite easily calculate the average:

data calc;
  set transposed;
  average=amount/account;
run;

If you MUST have things back, just transpose again:

proc transpose data=calc out=want(rename=(_name_=name));
  var amount account average;
  id month;
run;
PaigeMiller
Diamond | Level 26

@ss171 wrote:

Hi , Three is small help needed 

I have the below dataset 

data sample;
input name$ june july;
datalines ;
amount 170 140
account 2 4
;
run;

I need to create new row average which is amount/account 

output :

name  june july
amount 170 140
account  2 4
average 85 35

 


I don't understand the question — average of what? Are you trying to average the numbers shown next to amount and next to account? That makes no sense.

 

Furthermore, as others have pointed out, this is a very very poor layout to do anything in SAS. Calendar information (such as "June") should never be stored in variable names. It should be stored as the value of a variable named Month. Furthermore, dates in SAS are best set up as integers representing the number of days since 01JAN1960, and then all of the work SAS has done to properly deal with dates and months and weeks and years is available to you, and you don't have to figure out how to handle dates yourself.

 

Example: 

data have;
    input month :date9. amount account;
    format month monyy7.;
    cards;
01MAR2023 170 2
01APR2023 140 4
;

 

I do not include in the above code a method of averaging, as you have not explained the averages that you want. However, if you want the average over all months of amount, and the average over all months of account, this will provide the average (which is different than what you show)

 

proc means data=have mean;
    var amount account;
run;

 

This is a benefit of having the proper layout of your data, then every SAS PROC is available and will make your calculations easier. The results of PROC MEANS could be appended to your data if that's what you want (I do not show that code as I am still not sure what averages you want).

--
Paige Miller
ss171
Calcite | Level 5
Thanks @Paige Miller, but this is just a dummy data which I have created to understand the way of doing. Actual data is something different only.
PaigeMiller
Diamond | Level 26

@ss171 wrote:
Thanks @Paige Miller, but this is just a dummy data which I have created to understand the way of doing. Actual data is something different only.

Great. As everyone has stated, you have data in a very poor layout for working in SAS. You would find it much easier to transpose the data rather than work with the data in the layout you show.

 

 

--
Paige Miller
Ksharp
Super User
/*Here is SAS/IML solution.*/
data sample;
input name$ june july;
datalines ;
amount 170 140
account 2 4
;

proc iml;
use sample;
read all var{name};
read all var _num_ into x[c=vname];
close;
name=name//'average';
want=x//(x[1,]/x[2,]);
create want from want[r=name c=vname];
append from want[r=name];
close;
quit;
Aku
Obsidian | Level 7 Aku
Obsidian | Level 7

Proc SQL solution was pending, so here it is:

 

 
proc sql;
  select name as name, 
         june,
july
  from sample
  union
  select 'average' as name, 
         mean(june) as june,
mean(july) as july
  from sample;
quit;

 

mkeintz
PROC Star

I generally agree with the conventional wisdom on the advantages of structuring data in a long vs wide format.

 

But in this case - 2 rows (a sum row followed by a frequency row), a set of ID variables (only NAME in this case), and any number of columns, there is really no need for transpose, assuming you really do want an additional row of averages:

 

data sample;
input name$ june july;
datalines ;
amount 170 140
account 2 4
run;

data want;
  set sample  end=end_of_sample;
  output;
  array vals _numeric_;
  do over vals;
    vals=lag(vals)/vals;
  end;
  if end_of_sample then do;
    name='Average';
    output;
  end;
run;

This will produce the following log note:

NOTE: Missing values were generated as a result of performing an operation on missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      2 at 19:19

which can be avoided by using

    vals=sum(0,lag(vals))/vals;

inside the "DO OVER VALS" loop.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 10 replies
  • 1759 views
  • 1 like
  • 8 in conversation