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

Hi there,

 

I am using SAS v9.4. I have a dataset that looks like this:

 

refidtitleabstractreviewer_Areviewer_Breviewer_Creviewer_D
1how to have funthis is a study about how to have funincludeinclude  
2gaming and being awesomewe found that gaming makes you awesome  includeexclude

 

And I would like to transform it so it looks like this:

-

refidtitleabstractreviewer_1reviewer_2
1how to have funthis is a study about how to have funincludeinclude
2gaming and being awesomewe found that gaming makes you awesomeincludeexclude

 

That is, I would like to select the first TWO non-missing values across the range reviewer_A--reviewer_D in each row (each refid) and put the first in reviewer_1 and the second in reviewer_2.

 

Very much would appreciate any suggestions on how to program this using data steps or SQL. I have tried the proc sql coalescec approach but I haven't been able to get it to select the first and second values.

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

Given that you have only a few reviewers, this might be overkill.  But it will work here (as well as when you have many more possibilities):

 

data want;

set have;

array abcd {4} reviewer_A reviewer_B reviewer_C reviewer_D;

array new {2} $ 8 reviewer_1 reviewer_2;

i=0;

do j=1 to 4;

   if abcd{j} > ' ' then do;

      i + 1;

      if i < 3 then new{i} = abcd{j};

   end;

end;

drop i j reviewer_A reviewer_B reviewer_C reviewer_D;

run;

View solution in original post

3 REPLIES 3
Astounding
PROC Star

Given that you have only a few reviewers, this might be overkill.  But it will work here (as well as when you have many more possibilities):

 

data want;

set have;

array abcd {4} reviewer_A reviewer_B reviewer_C reviewer_D;

array new {2} $ 8 reviewer_1 reviewer_2;

i=0;

do j=1 to 4;

   if abcd{j} > ' ' then do;

      i + 1;

      if i < 3 then new{i} = abcd{j};

   end;

end;

drop i j reviewer_A reviewer_B reviewer_C reviewer_D;

run;

dantes
Calcite | Level 5

 

Thank you, Astounding.

 

Actually, this is a simplified example so your intuition is correct, there are in fact 7 reviewers so I would have reviewer_A to reviewer_G. Note that only two reviewers would ever review a single study.

 

In this case, would a correct code modification for the 7 reviewer situation be:

 

data want;

 

set have;

 

array abcdefg {7} reviewer_A reviewer_B reviewer_C reviewer_D reviewer_E reviewer_F reviewer_G;

 

array new {2} $ 8 reviewer_1 reviewer_2;

 

i=0;

 

do j=1 to 7;

 

   if abcdefg{j} > ' ' then do;

 

      i + 1;

 

      if i < 3 then new{i} = abcdefg{j};

 

   end;

 

end;

 

drop i j reviewer_A reviewer_B reviewer_C reviewer_D reviewer_E reviewer_F reviewer_G;

 

run;

 

 

??

 

Many thanks again.

Astounding
PROC Star

Yes, that looks fine.  

 

Your array names are up to you, so you could use "abc" instead of "abcdefg" ... just a choice you make like you choose names for new variables.

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 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
  • 3 replies
  • 720 views
  • 2 likes
  • 2 in conversation