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
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
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
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
Option NONE is not documented for CALL STDIZE routine, it seems... - PG
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.
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;
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
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;
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Lock in the best rate now before the price increases on April 1.
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.