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

Hi,

 

Is it possible to select more than one dataset in proc dataset??? eg. dynamically?

 

I want to put the same attrubutes and labels on a list of data (the list of the data is in a SAS datasæt).

 

All ideas to get the job done are appreciated.

 

I thinkt the code somthing like this - but it fails ....

 

proc datasets lib=XXX nolist;

modify table_x table_y ;

 

xattr add DS Type="Area_X";

xattr add DS Contact="Unit_U";

run;

 

Thanks in advance.

 

Rgrds,

Annette

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

For that situation, the right tool for the job is CALL EXECUTE.  It is a DATA step statement that lets you build code that runs after the current DATA step.  Technically, it is part of macro language, but you won't see any % or &.  Here's a brief example.

 

proc sort data=have;

by library;

run;

data _null_;

set have;

by library;

if first.library then call execute('proc datasets lib=' || library || ' nolist;');

call execute('modify ' || table || ';');

call execute('xattr add DS Type="' || type || '";');

call execute('xattr add DS Contact="' || contact || '";');

call execute('run;');

if last.library then call execute('quit;');

run;

 

I think I have all the pieces here, but you may have to debug as you test it.

View solution in original post

16 REPLIES 16
Astounding
PROC Star

You can only select one data set at a time, but you can still select dynamically and get to all of them one at a time.  For example, this would work:

 

 

proc datasets lib=XXX nolist;

modify table_x;

xattr add DS Type="Area_X";

xattr add DS Contact="Unit_U";

run;

modify table_y;

xattr add DS Type="Area_X";

xattr add DS Contact="Unit_U";

run;

quit;

 

Shmuel
Garnet | Level 18

You can use SAS macro to shorten your code:

 

%macro shr;    /* you may add as much common lines as need */

xattr add DS Type="Area_X";

xattr add DS Contact="Unit_U";

%mend;

 

proc datasets lib=XXX nolist;

modify table_x;  %shr;

modify table_y; %shr;

quit;

 

I'm not sure is it possible to modify more than one file at a time.

Anyway ther is no need to copy shared lines. It can be done easily by macro;

Please check it;

ANLYNG
Pyrite | Level 9

I wish to make it more dynamically. eg. do you have an example if i put the classification in an variable in a data set (together with dataset name) and how to loop it into a dynamic macro variable which rund through the data set?

Astounding
PROC Star

It sounds like it would be easy.  But it's not clear what the incoming data would look like, and how it is supposed to be used by the program.  Can you give an example?

Shmuel
Garnet | Level 18

hello,

I have attached a SAS program - an example.

First two steps were to create test data, the rest is a code to add label and change format of variables.

Run the 1st two steps and look at the data sets: the date is not formated and the variable i  - should be labeled as "KEY".

Now run the rest of the pragram (or the whole program as one unit);

 

Look at the log: using "options mprint" in the program enables demostrate how the macro is developed and embeded;

Look again at the datasests EXPML1 and EXMPL2; change to view labels

instead of columns. You will see the outcome of the MODIFY statements;

 

With hope it is more clear now.

 

Shmuel

Shmuel
Garnet | Level 18

I don't understand your situation.

What do you mean by "...put the classification in an variable in a data set..." ?

What do you mean by "... loop it into a dynamic macro variable which rund through the data set" ?

 

I may help you if you give an example of your inputs and what you want to be on the outputs.

 

Shmuel

ANLYNG
Pyrite | Level 9

What I was thinking was to make this dynamically. I have putted the classification variable into a SAS dataset. In this structure:

library table type     contact

XXX     x     Area_X    Unit_U

YYY     z     Area_X    Unit_Z

 

And wish to loop these variables and use like this:

 

proc datasets lib=&library. nolist;

modify table_&table.;

xattr add DS Type=&type.;

xattr add DS Contact=&contact.;

run;

 

Do you have some ideas to make it smart?

Shmuel
Garnet | Level 18

I have the feeling that we use same word MODIFY but understand it differently.

 

Proc Datasets ... Modify ... enables modifying of variable attributes like: rename, variable label, format (how to display it) etc

but not their value in the data set observations.

 

I have no idea what you mean by AREA_X, UNIT_Z - are those variable values that you want to replace in all observations of the data set ?

 

Please run the next code and see what RETAIN do:

 

data test;

retain x 'Constant';  /* no equal sign is needed */

do i=1 to 5; output; end;

run;

 

Shmuel

ANLYNG
Pyrite | Level 9

the idea is that the input (libane, data and label)  is dynamic and read from a data set and used inside  proc datasets.

Shmuel
Garnet | Level 18

I got your point.

In this case I shall not use macro language, though it is possible but mutch more compicated.

Instead I shall show here a method that I have used a lot of times.

 

Let say your file contains next variables:

  -  LIB stands for Library

  -  DSN stand for dataset Name

  -  var1 contains attribute 1  (TYPE)

  -  var2 contains attribute 2  (LABEL)

  -  and so on, as mutch as you need

 

Let's call your file ARGS (arguments);

By the method, I write program A and run it to generate program B, using the fact that each program is a text file.

I can look at the generated program B, make changes to program A if needed and rerun it until satisfaction.

 

Then I run program B to do the wanted job.

 

Here is a schematic prgram A:

 

proc sort data=ARGS; by LIB  DSN; run;     /* needed for proc datasets */

filename generated '... any path and name ...';

data _NULL_;

    set ARGS end=eof;

      by LIB  DSN;

    file generated;

 

    length pgm_line $80;  /* generated program line. you may change length according to need */

 

   if first.LIB then do;

       pgm_line = 'Proc Datasets lib=' || LIB || ' nolist; ';  

       put pgm_line;

  end;

 

   if first.DSN then do;

       pgm_line = 'Modify ' || DSN || ';' ;

       put pgm_line;

   end;

   

   pgm_line = 'TYPE=' || var1 || ';' ;

   put pgm_line;

   pgm_line = 'LABEL=' || var2 || ';' ;

   put pgm_line;

 

   *** continue as much as you need ***;

   

   if last.LIB or eof then do;

       pgm_line = 'Quit; Run;' ;

       put pgm_line;

  end;

RUN;   /*  end od program A */

 

Now run this program and look at the generated output.

Addapt it to your needs and rerun.

When satisfied, do %INCLUDE generated; and run it.

 

I hope I realy got your point;

Shmuel

Astounding
PROC Star

For that situation, the right tool for the job is CALL EXECUTE.  It is a DATA step statement that lets you build code that runs after the current DATA step.  Technically, it is part of macro language, but you won't see any % or &.  Here's a brief example.

 

proc sort data=have;

by library;

run;

data _null_;

set have;

by library;

if first.library then call execute('proc datasets lib=' || library || ' nolist;');

call execute('modify ' || table || ';');

call execute('xattr add DS Type="' || type || '";');

call execute('xattr add DS Contact="' || contact || '";');

call execute('run;');

if last.library then call execute('quit;');

run;

 

I think I have all the pieces here, but you may have to debug as you test it.

Shmuel
Garnet | Level 18

The outcome of "CALL EXECUTE" and the generated program are the same;

The benefit of generated program is the ability to stop and control before real execution.

 

Shmuel

ANLYNG
Pyrite | Level 9

Look really nice-thank you very much......it helps me....

ANLYNG
Pyrite | Level 9

but as far i can test it only takes the first library and not the following. ...

 

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
  • 16 replies
  • 1471 views
  • 0 likes
  • 3 in conversation