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

Hi there,

I have a list of numeric variables which should be assigned the value of 1 if they haven’t been found in a hash table lookup.

The call missing routine assigns missing values to a list of variables e.g. call missing(scalar1, scalar2, scalar3). Does a similar routine exist which can assign the value of 1 to a list of variables?

Example:

data data_out ;

   if 0 then do;

      set data_table ;

      set work.hash_lookup;

   end;

   set data_table ;

   if _N_= 1 then do;

      declare hash ht(dataset: 'work.hash_lookup');

      ht.definekey('key');

      ht.definedata('scalar1','scalar2','scalar3');

      ht.definedone();

   end;

   if ht.find() ne 0 then call missing(scalar1, scalar2, scalar3) ;

   variable_adj = variable * scalar1 * scalar2 * scalar3;

run;


Thanks in advance,

Sean

1 ACCEPTED SOLUTION

Accepted Solutions
data_null__
Jade | Level 19

You can use CALL STDIZE to do the same trick in a data step.


1    data _null_;
2       array scalar[4];
3       put (scalar[*]) (=);
4       call stdize('missing=',1,'none',of scalar[*]);
5       put (scalar[*]) (=);
6       run;

scalar1=. scalar2=. scalar3=. scalar4=.
scalar1=1 scalar2=1 scalar3=1 scalar4=1
                                                                                                                     

View solution in original post

7 REPLIES 7
Ksharp
Super User

NO. I don't think there is such a call routine in SAS. But you can firstly use call missing  , them set missing value be 1.

........

call misisng(.........);

...........

run;

proc stdize data=want reponly missing=1;

var scalar1-scalar4 ;

run;

Xia Keshan

data_null__
Jade | Level 19

You can use CALL STDIZE to do the same trick in a data step.


1    data _null_;
2       array scalar[4];
3       put (scalar[*]) (=);
4       call stdize('missing=',1,'none',of scalar[*]);
5       put (scalar[*]) (=);
6       run;

scalar1=. scalar2=. scalar3=. scalar4=.
scalar1=1 scalar2=1 scalar3=1 scalar4=1
                                                                                                                     
PGStats
Opal | Level 21

Option NONE is not documented for CALL STDIZE routine, it seems... - PG

PG
data_null__
Jade | Level 19

I kept trying REPONLY but that didn't work so one day I tried NONE.  Go figure.

For an array probably CALL POKE is faster.  I've also used SET POINT= to re-initialize an array, works well enough from my point of view.

Patrick
Opal | Level 21

You could also add an additional row to the hash table for such cases as done in code below:

data work.hash_lookup;

  do key=1,2,3;

    scalar1=key;

    scalar2=key+2;

    scalar3=key+10;

    output;

  end;

run;

data data_table;

  variable=100;

  do key=1,3,5;

    output;

  end;

run;

data data_out;

  if _N_= 1 then

    do;

      if 0 then

        do;

          set data_table;

          set work.hash_lookup;

        end;

      declare hash ht(dataset: 'work.hash_lookup');

      ht.definekey('key');

      ht.definedata('scalar1','scalar2','scalar3');

      ht.definedone();

      key=-1;scalar1=1;scalar2=1;scalar3=1;

      ht.add();

    end;

  set data_table;

  if ht.find() ne 0 then ht.find(key:-1);

  variable_adj = variable * scalar1 * scalar2 * scalar3;

run;

In case you want also to set the scalar to 1 in cases where the lookup succeeds but one or several of the scalar are either missing or zero then you could use code as below:

data data_out;

  if _N_= 1 then

    do;

      if 0 then

        do;

          set data_table;

          set work.hash_lookup;

        end;

      declare hash ht(dataset: 'work.hash_lookup');

      ht.definekey('key');

      ht.definedata('scalar1','scalar2','scalar3');

      ht.definedone();

    end;

  set data_table;

  if ht.find() ne 0 then call missing(scalar1, scalar2, scalar3) ;

  variable_adj=

    variable *

    (ifn(scalar1 not in (0,.),scalar1,1)) *

    (ifn(scalar2 not in (0,.),scalar2,1)) *

    (ifn(scalar3 not in (0,.),scalar3,1));

run;

jh_ti_bw
Obsidian | Level 7

Hi,

a little macro will do the job.

%macro call_assign(arrayname,Varlist,Value, length=);

  %if %length(&Length.)>0 %then %do;

    Length &varlist. &Length.;

  %end;

  array &arrayname. &Varlist.;

  do over &arrayname.;

    &arrayname. = &value.;

  end;

%mend;

How to use:

data data_out ;

   if 0 then do;

      set data_table ;

      set work.hash_lookup;

   end;

   set data_table ;

   if _N_= 1 then do;

      declare hash ht(dataset: 'work.hash_lookup');

      ht.definekey('key');

      ht.definedata('scalar1','scalar2','scalar3');

      ht.definedone();

   end;

   if ht.find() ne 0 then do;

     %call_assign(ScalarArray,scalar1 scalar2 scalar3,1) ;

   end;

   variable_adj = variable * scalar1 * scalar2 * scalar3;

run;


The arrayname must be unique in the datastep;

You can assign only numeric variables or only character variables in one step.

If you want for new character values an other length then the length of the value, you have to use the length parameter.


Example:

%call_assign(NewChars, c1 - c10, "EMPTY", length = $20);


Jan

Reeza
Super User

You could initialize them in an array statement as well, I think as long as setting them to 1 initially isn't an issue either.

data _null_;

   array scalar[4] scalar1-scalar4 (4*1);

   put (scalar

  • ) (=);
  • run;

    OR

    data _null_;

       array scalar[4] (4*1);

       put (scalar

  • ) (=);
  • run;

    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 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
    • 7 replies
    • 1684 views
    • 6 likes
    • 7 in conversation