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

I need to implement below in SAS DI without using custom code, Can we achieve it by using only the existing SAS DI transformations?

proc sort DATA=AIN out=A;

By AID AMEM;

data pt_all_LAC_curr (keep= AID AMEM All_AMEMs) ;
set A  ;
by AID AMEM;

length All_AMEMs $255;

if first.AID then do;
  retain All_AMEMs;
  All_AMEMs=cat(trim(Plan_mgmt_team_member)," (",trim(Participant_Management_Role_Desc),")");
  end;

else do All_AMEMs=catx(" NEXT VAL ",cat(trim(Plan_mgmt_team_member)," (",trim(Participant_Management_Role_Desc),")"));

end;
  if last.AID then output;

run;

In SAS DI 4.21 or 4.8

For example:

INPUT

AID AMEM Plan_mgmt_team_member Participant_Management_Role_Desc

1     5          AA                                        AA_DESC

1     5          BB                                        BB_DESC

1     5          CC                                        CC_DESC         

2     6          DD                                        DD_DESC

2     6          EE                                        EE_DESC

2     6          FF                                        FF_DESC

Expected OUTPUT:

AID AMEM All_AMEMs

1     5          AA  (AA_DESC) NEXT VAL BB (BB_DESC) NEXT VAL CC (CC_DESC)

2     6          DD (DD_DESC) NEXT VAL EE (EE_DESC) NEXT VAL FF (FF_DESC)

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

You can do what you're asking for by "tricking" DIS and ingest your data step logic using a Splitter; but it's ugly and I wouldn't go for it. The input to the Splitter would need to be a table with target column "All_AMEMs " already existing (but then drop it in the Splitter using the option for input tables) - this needs to be done to overcome the mapping step generated by the Splitter as else the generated string for "ALL_AMEMs" gets wiped out.

In the row selection bit you can write code as below:

1;

by AID AMEM;

length All_AMEMs $255;

retain All_AMEMs;

if first.AID then do;

  call missing(All_AMEMs);

end;

All_AMEMs=catx(' ',All_AMEMs,Plan_mgmt_team_member,'(',Participant_Management_Role_Desc,')');

if last.AID

As said: Really ugly and also no more really metadata driven so I don't see a lot of value to go down such a path.

I consider it as acceptable to have user written code for a special case like yours as long as you're using the generated macro variables as far as possible. Something like:

data &_output;

  set &_input;

  keep &_OUTPUT_keep;

  by AID AMEM;

  length All_AMEMs $255;

  retain All_AMEMs;

  All_AMEMs=catx(' ',All_AMEMs,Plan_mgmt_team_member,'(',Participant_Management_Role_Desc,')');

  if last.AID then

    do;

      output;

      call missing(All_AMEMs);

    end;

run;

I'm attaching the .spk of my sample DIS job - but it has been written with DIS4.9 so not sure if you will be able to import it.

View solution in original post

5 REPLIES 5
Patrick
Opal | Level 21

What DIS version?

Actually: Looking at your code would below syntax return the same result? Or is the source data set sorted by a second variable?

data pt_all_LAC_curr  ;

  set A  ;

  by AID AMEM;

  if first.AID;

  length All_AMEMs $255;

  All_AMEMs=cat(trim(Plan_mgmt_team_member)," (",trim(Participant_Management_Role_Desc),")");

run;

Below SQL could work and would be easy to implement using DIS - but it really depends on how your data looks like which I can't tell from you code. Can you provide a representative sample?

proc sql;

  create table pt_all_LAC_curr as

    select DISTINCT

      *,

      cat(trim(Plan_mgmt_team_member)," (",trim(Participant_Management_Role_Desc),")") as All_AMEMs length=$255

    from A

  ;

quit;

ven
Calcite | Level 5 ven
Calcite | Level 5

Hi Patrick,

There is actually an else clause which prevent the use of method you described.

I have updated the question as below to show it.

In SAS DI Version: 4.21 or 4.8

proc sort DATA=AIN out=A;

By AID AMEM;

data pt_all_LAC_curr (keep= AID AMEM All_AMEMs) ;
set A  ;
by AID AMEM;

length All_AMEMs $255;

if first.AID then do;
  retain All_AMEMs;
  All_AMEMs=cat(trim(Plan_mgmt_team_member)," (",trim(Participant_Management_Role_Desc),")");
  end;

else do All_AMEMs=catx(" NEXT VAL ",cat(trim(Plan_mgmt_team_member)," (",trim(Participant_Management_Role_Desc),")"));

end;
  if last.AID then output;

run;

For example:

INPUT

AID AMEM Plan_mgmt_team_member Participant_Management_Role_Desc

1     5          AA                                        AA_DESC

1     5          BB                                        BB_DESC

1     5          CC                                        CC_DESC         

2     6          DD                                        DD_DESC

2     6          EE                                        EE_DESC

2     6          FF                                         FF_DESC

Expected OUTPUT:

AID AMEM All_AMEMs

1     5          AA  (AA_DESC) NEXT VAL BB (BB_DESC) NEXT VAL CC (CC_DESC)

2     6          DD (DD_DESC) NEXT VAL EE (EE_DESC) NEXT VAL FF (FF_DESC)

Patrick
Opal | Level 21

You can do what you're asking for by "tricking" DIS and ingest your data step logic using a Splitter; but it's ugly and I wouldn't go for it. The input to the Splitter would need to be a table with target column "All_AMEMs " already existing (but then drop it in the Splitter using the option for input tables) - this needs to be done to overcome the mapping step generated by the Splitter as else the generated string for "ALL_AMEMs" gets wiped out.

In the row selection bit you can write code as below:

1;

by AID AMEM;

length All_AMEMs $255;

retain All_AMEMs;

if first.AID then do;

  call missing(All_AMEMs);

end;

All_AMEMs=catx(' ',All_AMEMs,Plan_mgmt_team_member,'(',Participant_Management_Role_Desc,')');

if last.AID

As said: Really ugly and also no more really metadata driven so I don't see a lot of value to go down such a path.

I consider it as acceptable to have user written code for a special case like yours as long as you're using the generated macro variables as far as possible. Something like:

data &_output;

  set &_input;

  keep &_OUTPUT_keep;

  by AID AMEM;

  length All_AMEMs $255;

  retain All_AMEMs;

  All_AMEMs=catx(' ',All_AMEMs,Plan_mgmt_team_member,'(',Participant_Management_Role_Desc,')');

  if last.AID then

    do;

      output;

      call missing(All_AMEMs);

    end;

run;

I'm attaching the .spk of my sample DIS job - but it has been written with DIS4.9 so not sure if you will be able to import it.

ven
Calcite | Level 5 ven
Calcite | Level 5

Hi Partick,
Thank you for the reply, as for the package I cannot import it, Can you pl. attach the generated code of your SAS DI job.

Thanks a lot

Patrick
Opal | Level 21

Attached the code of below flow.

Node 1 creates some sample data

Node 2 adds variable "All_AMEMs" to the source for the splitter

Node 3 is the Splitter code creating table Want

Node 4 is the alternative approach using user written code creating table Want_2

Capture.PNG

Capture.PNG  Capture.PNG

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
  • 5 replies
  • 1165 views
  • 0 likes
  • 2 in conversation