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

Hello,

 

I know there are different ways to do what I want to do but I just can manage to make it work..

I would like to do this in a proc SQL in one select statement.

 

I have this table named test.

I want to create a new column (D_IL8) that would be IL8 - (mean IL8 for positive outcomes)

Mean IL8 for positive outcomes = (34+23+34+28+27)/5 = 29.20

So column D-IL8 would be IL8 value for that person - 29.20

 

Name

IL8OutcomeD_IL8
Marie34,00Positive 
Martha56,00Negative 
Angela23,00Positive 
Jodie34,00Positive 
Alexe44,00Negative 
Jane33,00Negative 
Cassandra28,00Positive 
Olivia27,00Positive 
Anna41,00Negative 
Sarah42,00Negative 

 

Does anyone knows how to do that ?

 

Thank you so much

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User
proc sql;
create table want as
select *, IL8 - mean(case when Outcome="Positive" then IL8 else . end) as D_IL8
from have;
quit;

Untested, but this should work in theory.

 


@cfortin wrote:

Hello,

 

I know there are different ways to do what I want to do but I just can manage to make it work..

I would like to do this in a proc SQL in one select statement.

 

I have this table named test.

I want to create a new column (D_IL8) that would be IL8 - (mean IL8 for positive outcomes)

Mean IL8 for positive outcomes = (34+23+34+28+27)/5 = 29.20

So column D-IL8 would be IL8 value for that person - 29.20

 

Name

IL8 Outcome D_IL8
Marie 34,00 Positive  
Martha 56,00 Negative  
Angela 23,00 Positive  
Jodie 34,00 Positive  
Alexe 44,00 Negative  
Jane 33,00 Negative  
Cassandra 28,00 Positive  
Olivia 27,00 Positive  
Anna 41,00 Negative  
Sarah 42,00 Negative  

 

Does anyone knows how to do that ?

 

Thank you so much


 

View solution in original post

13 REPLIES 13
Reeza
Super User
proc sql;
create table want as
select *, IL8 - mean(case when Outcome="Positive" then IL8 else . end) as D_IL8
from have;
quit;

Untested, but this should work in theory.

 


@cfortin wrote:

Hello,

 

I know there are different ways to do what I want to do but I just can manage to make it work..

I would like to do this in a proc SQL in one select statement.

 

I have this table named test.

I want to create a new column (D_IL8) that would be IL8 - (mean IL8 for positive outcomes)

Mean IL8 for positive outcomes = (34+23+34+28+27)/5 = 29.20

So column D-IL8 would be IL8 value for that person - 29.20

 

Name

IL8 Outcome D_IL8
Marie 34,00 Positive  
Martha 56,00 Negative  
Angela 23,00 Positive  
Jodie 34,00 Positive  
Alexe 44,00 Negative  
Jane 33,00 Negative  
Cassandra 28,00 Positive  
Olivia 27,00 Positive  
Anna 41,00 Negative  
Sarah 42,00 Negative  

 

Does anyone knows how to do that ?

 

Thank you so much


 

cfortin
Calcite | Level 5

Exactly !!

It's exactly what I needed, thank you so much.

I don't totally understand it though..  it's keeping only the IL8 values of outcome=positive and then it does the mean of it ?

Reeza
Super User

@cfortin wrote:

 it's keeping only the IL8 values of outcome=positive and then it does the mean of it ?


It essentially creates a new (invisible) column of data that's either missing or the value when positive and takes the mean of that and adds to each row.

novinosrin
Tourmaline | Level 20

Hi @cfortin 

 

Are you asking for this

 



data have;
input Name :$10. IL8 	Outcome	: $12.;
cards;
Marie	34.00	Positive	 
Martha	56.00	Negative	 
Angela	23.00	Positive	 
Jodie	34.00	Positive	 
Alexe	44.00	Negative	 
Jane	33.00	Negative	 
Cassandra	28.00	Positive	 
Olivia	27.00	Positive	 
Anna	41.00	Negative	 
Sarah	42.00	Negative	 
;


proc sql;
create table want as
select *, mean(ifn(outcome='Positive',il8,.)) as d_il8 format=8.2
from have;
quit;
cfortin
Calcite | Level 5

It's working too !! thanks.

just need to add IL8 - before the mean.

novinosrin
Tourmaline | Level 20

An ardent follower of @SASKiwi (i call him boolean champ)  would also attempt the following

 

 

proc sql;
create table want as
select *, sum((outcome='Positive')*il8)/sum(outcome='Positive') as d_il8 format=8.2
from have;
quit;

 

Sir @SASKiwi   you got me addicted to booleans. I blame you for it! lol

PaigeMiller
Diamond | Level 26

An answer that doesn't require PROC SQL. (Assumes data is sorted by OUTCOME)

 

proc stdize data=have method=mean out=want sprefix=D_;
    by outcome;
    var il8;
run;

My problem with the SQL approaches is that the code works for the case where you only want to do this for the values where OUTCOME='POSITIVE', but you (or someone else who is reading along) will eventually want it for OUTCOME="NEGATIVE" and yes indeed, extra programming in SQL is needed to make this work, but PROC STDIZE requires no additional programming, and it works for any number of values that OUTCOME can have, even if it is more than two.

--
Paige Miller
Reeza
Super User
In that method negative values would not be subtracted from the positive mean though, so it's not quite the same calculation, though more common.
PaigeMiller
Diamond | Level 26

@Reeza wrote:
In that method negative values would not be subtracted from the positive mean though, so it's not quite the same calculation, though more common.

I don't understand this. As far as I know, negative values are handled properly by PROC STDIZE.

--
Paige Miller
Reeza
Super User
The calculation the OP wants is ObservedValue - Mean(positiveValues) for all records wether positive or negative. Your code won't do that, the BY statement means that the Negative values would be handled independently.
PaigeMiller
Diamond | Level 26

@Reeza wrote:
The calculation the OP wants is ObservedValue - Mean(positiveValues) for all records wether positive or negative. Your code won't do that, the BY statement means that the Negative values would be handled independently.

I would not agree with this wording.

 

I would say that the OP wants ObservedValue - Mean (positive OUTCOMEs)

 

I would say that the negative OUTCOMEs would be handled independently by PROC STDIZE, which gives the proper result for the data which has OUTCOME='POSITIVE'.

--
Paige Miller

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


Register now!

How to connect to databases in SAS Viya

Need to connect to databases in SAS Viya? SAS’ David Ghan shows you two methods – via SAS/ACCESS LIBNAME and SAS Data Connector SASLIBS – in this video.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 13 replies
  • 4091 views
  • 10 likes
  • 4 in conversation