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

 

 

Hi,

 

How can I write a macro to efficiently divide all of the numeric variables in my dataset against

all other numeric variables in my dataset?  For example:

 

Var1 Var2 Var3

1.       2.     4

 

Would yield:

 

Var1divVar2 = .5

Var1divVar3 = .25

 

Thanks!!

1 ACCEPTED SOLUTION

Accepted Solutions
PGStats
Opal | Level 21

Straightforward programming, no macros :

 

data have;
input id $ a b c d e;
datalines;
Ballard 1 2 3 4 5 
Reeza 6 7 8 9 0 
Alan 2 3 4 5 .
;

data long;
set have;
array _num _numeric_;
obs = _n_;
do vorder = 1 to dim(_num);
    vname = vname(_num{vorder});
    value = _num{vorder};
    output;
    end;
keep _character_ obs vorder value;
run;

proc sql;
create table longRatios as
select 
    num.obs,
    num.id,
    cats(num.vname, "_div_", div.vname) as ratioName,
    case
        when div.value = 0 then .
        when missing(num.value) then .
        when missing(div.value) then .
        else num.value / div.value 
        end as ratio format=5.2
from 
    long as num inner join 
    long as div on num.obs=div.obs and num.vname ne div.vname
order by obs, num.vorder, div.vorder;
quit;

proc transpose data=longRatios out=ratios(drop=_name_ obs);
by obs id;
var ratio;
id ratioName;
run;

proc print data=ratios noobs; run;

 

PG

View solution in original post

7 REPLIES 7
Reeza
Super User

Can you provide some more sample data and output?

 

I'm curious as to what the logic is behind this.

 

Also, do you have SAS IML, this sounds a lot like a matrix operation.

AlanCT
Calcite | Level 5

Hi 

 

really nothing more to describe.

i just need to create ratios between each and every variable in a large dataset.

 

I'd appreciate any advice on how to do this efficiently.

 

thanks!,

ballardw
Super User

Is this between values only on one row (observation) of a data set or are you looking to do this calculation across rows as well?

 

If the last is what you want I suggest that provide an example with 3 or 4 variables, 3 or 4 rows of input data and what you expect the output to look like.

 

If you have currently 10 variables then you are going to end up with 45 new variables. Is that what you intend?

Astounding
PROC Star

First, you need to do your homework.  Do you want Var1DivVar2 as well as Var2DivVar1?  If the denominator is 0, what would you like the result to be?  If either the numerator or denominator is missing, what would you like the result to be?  If you are starting with 100 numeric variables, are you prepared to end up with a data set with 10,000 variables?  

 

What variable names will you use to hold the results?  If you start with variable names that are 20 characters long, you won't have room to create a new variable name that is 40 characters long.  So how will you map the ratios to the variables that went into the calculations?

 

Truthfully, the programming is fairly straightforward and may not even involve macros.  It's the preparation that is difficult.

PGStats
Opal | Level 21

Straightforward programming, no macros :

 

data have;
input id $ a b c d e;
datalines;
Ballard 1 2 3 4 5 
Reeza 6 7 8 9 0 
Alan 2 3 4 5 .
;

data long;
set have;
array _num _numeric_;
obs = _n_;
do vorder = 1 to dim(_num);
    vname = vname(_num{vorder});
    value = _num{vorder};
    output;
    end;
keep _character_ obs vorder value;
run;

proc sql;
create table longRatios as
select 
    num.obs,
    num.id,
    cats(num.vname, "_div_", div.vname) as ratioName,
    case
        when div.value = 0 then .
        when missing(num.value) then .
        when missing(div.value) then .
        else num.value / div.value 
        end as ratio format=5.2
from 
    long as num inner join 
    long as div on num.obs=div.obs and num.vname ne div.vname
order by obs, num.vorder, div.vorder;
quit;

proc transpose data=longRatios out=ratios(drop=_name_ obs);
by obs id;
var ratio;
id ratioName;
run;

proc print data=ratios noobs; run;

 

PG
data_null__
Jade | Level 19
divide(num.value,div.value) as ratio format 5.2

Maybe

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 7 replies
  • 6362 views
  • 2 likes
  • 6 in conversation