BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
PopCorn14
Obsidian | Level 7

Hi,

 

I found these lines of code in our big application but I really don't understand the first lines.

I don't understand the condition "if (0) then modify" the output dataset.

What is the purpose  of that modify at this location?

Thank you so much for also giving an another example with if (0) then modify.....

 

 

data work.dataset;
      if (0) then modify work.dataset;

      set work.processing(where=(indicator)) end=__Last__;
      retain __Count__ 0;
      __Count__ = __Count__ + 1;
     output;
     if (__Last__) then call symputx('incatorCount',__Count__);
run;

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

As already demonstrated by others this code creates the same data as a Proc Append with the force option would do.

proc append base=work.dataset data=work.processing(where=(indicator)) force;
run;

Because it's done via a SAS datastep it also allows for additional logic in the same pass through the data.

 

The code demonstrates that the one who implemented it has a very solid understanding of the SAS datastep BUT.... if that's not some SAS R&D provided and maintained piece of code in the bowels of some SAS solution then it's for me also an example how not to implement unless there is a very good reason to do so and then only with a lot of comment/documentation directly in the code.

Writing code that's easy to understand and maintain is imho most of the time of higher importance than to potentially save a few seconds of runtime. 

 

View solution in original post

12 REPLIES 12
PaigeMiller
Diamond | Level 26

The part

 

if (0)

 

is never true, so this line will never do anything.

--
Paige Miller
PopCorn14
Obsidian | Level 7

Thank you Paige.  I understand that it will not execute but with a modify, I don't see what it does.

 

We do use if (0) with hash table.

Intead of using the length statement, we can use a non-executing SET statement .

data country;
        if 0 then set orion.continent;
       if _n_=1 then do;
               declare hash
            ContName(dataset:'orion.continent');
            ContName.definekey('ContinentID');
           ContName.definedata('ContinentName');
          ContName.definedone();
     end;
    set orion.country(keep=ContinentID Country   CountryName);
     if ContName.find()=0;
run;

 

Therefore I don't know with modify if it has another purpose.

Amir
PROC Star

Hi,

 

If you are not sure what it does then you can try backing up the work.dataset data set, commenting out that if (0) line and running the code again with your data and then see what difference it makes by maybe running a proc compare between the data sets.

 

This is a general principle that can be used in other scenarios too.

 

 

Thanks & kind regards,

Amir.

ballardw
Super User

It's going to depend a bit on what the current content of the work.dataset might be.

Basically modify means it will add records from the data set on the other SET to work.dataset.

However since MODIFY does not allow adding variables to the data set then the _count_ variable is not added.

 

Depending on what you do with work.dataset later it looks like kludgy way to count observations to get a macro variable.

Quentin
Super User

I don't use MODIFY much (ever?).

 

Even though you have if (0), it's still working at compile time to make it update the dataset rather than over-write it, and it prevents the MODIFY statement from reading any data when the step executes.  It looks looks like it's basically similar to using PROC APPEND .

 

I played with code like:

 

data want ;
 input x y $1.;
 cards ;
1 A
2 B
;

data foo ;
 input x ;
 cards ;
3
4
;
run ;

data want ;
  if 0 then modify want ;
  set foo ;
  output ;
run ;

which returns:

Obs    x    y

 1     1    A
 2     2    B
 3     3
 4     4

If you change to if (1) then modify want, it will return:

 Obs    x    y

  1     1    A
  2     2    B
  3     3    A
  4     4    B
BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
PopCorn14
Obsidian | Level 7
Thank you @Quentin for making me realize that it behaves like a PROC APPEND.
mkeintz
PROC Star

Since the 

 if (0) then modify work.dataset;

statement precedes the

set work.processing(where=(indicator)) end=__Last__;

statement, the SAS DATA step compiler will build the program data vector with the variables from work.dataset preceding the variables from work.processing.

 

And if they have the same variables (or have some common variables), those variables will be ordered corresponding to the order in work.dataset, (not the order in work.processing) since it was the first dataset name encountered.

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
PopCorn14
Obsidian | Level 7
Thank you @mkeintz for the explanation about the compiler and pdv.
Patrick
Opal | Level 21

As already demonstrated by others this code creates the same data as a Proc Append with the force option would do.

proc append base=work.dataset data=work.processing(where=(indicator)) force;
run;

Because it's done via a SAS datastep it also allows for additional logic in the same pass through the data.

 

The code demonstrates that the one who implemented it has a very solid understanding of the SAS datastep BUT.... if that's not some SAS R&D provided and maintained piece of code in the bowels of some SAS solution then it's for me also an example how not to implement unless there is a very good reason to do so and then only with a lot of comment/documentation directly in the code.

Writing code that's easy to understand and maintain is imho most of the time of higher importance than to potentially save a few seconds of runtime. 

 

PopCorn14
Obsidian | Level 7

Thank you very much @Patrick .

Yes indeed, I double-checked the code by playing with it and it does a Proc Append force without having all the warnings like:

 

WARNING: Variable X was not found on BASE file. The variable will not be added to the BASE file.

WARNING: Variable A was not found on DATA file.

 

I do agree without good documentation, it is not worth it.

Patrick
Opal | Level 21

@PopCorn14 You can suppress such warnings by adding the NOWARN option.

proc append base=work.dataset data=work.processing(where=(indicator)) force nowarn;
run;

 

PopCorn14
Obsidian | Level 7
Oh even better. Merci @Patrick for that option.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 12 replies
  • 1259 views
  • 8 likes
  • 7 in conversation