BookmarkSubscribeRSS Feed
deleted_user
Not applicable
Hey folks

Some of my continuous variables have default values that signify various things to the owners of the data. The problem is that the default values are extremes which skew my means calculation so I need to remove these.

This is easily done by listing the defaults in a field (comma separated with a char type) on my control table and using an array to process this. Code as below

*Count the number of default values for each variable;

data defs1;
set control.continuous_vars (where=(chlist="&chlist"));
if default ne '' then do;
noofcoms = count(default,",")+1;
end;
else noofcoms=0;
run;


*Find the maximum number of default values for this data source as this defines the size of the array;

proc sql;
select max(noofcoms) into :numdef
from defs1;
quit;

%let numdef = &numdef;
%put Max no. of unique default values = &numdef;

%if &numdef gt 0 %then %do;


*Create an array for each variable -
- use this to decide whether the variable is a default value.
- create a new column to count the number of default values.
- set the value of the var to null if there is a default value so that this does not skew the means.
- if a default value is found stop the array from processing so that values are not overwritten and to save resource.;

data defs (drop=g _temporary_ val:);
retain defs_1-defs_&ww 0;
set work.this_month_&chlist;
%do v=1 %to &ww;
%if &&default_&v ne %then %do;
array defaults_&v._ val1-val&numdef. _temporary_;
do g = 1 to &numdef.;
defaults_&v._{g} = scan("&&default_&v",g,",");
if defaults_&v._{g} = &&varname_&v then do;
defs_&v = 1;
&&varname_&v=.;
goto complete_&v;
end;
end;
complete_&v:
%end;
%end;
run;
%end;


The problem comes in if the default value is a negative as SAS then sees this as a character and not a number and errors. If I put a %eval around the default value (&&default_&v) it errors if it is null as the macro variable does not exist. How can I get around this
2 REPLIES 2
Patrick
Opal | Level 21
Hi

Instead of trying to debug and fix this code I would choose another approach.

What you've coded is in my opinion hard to read and too complicated.

I can think of various ways to solve your problem without using macro language, i.e:
1. a merge using "in" and in case you've got data from the control table set your variable to missing.
2. create a informat from your control table and set the label to missing. Don't use "other" (HLO).
3. Use a modify statement and treat the control data as transaction data set.
4. Use a hash lookup (see example below)

/* Hash lookup approach */
data DefaultValues;
DefVal=5;
output;
DefVal=-3;
output;
run;

data have;
do var=-5 to 5;
output;
end;
run;

data want(drop=DefVal);
/* declare hash table */
if _n_=1 then
do;
declare hash h(dataset: "DefaultValues", hashexp: 4);
h.defineKey('DefVal');
h.defineDone();
call missing(DefVal);
end;

set have;

/* set variable to missing if value exists in lookup table */
DefVal=var;
if h.check() =0 then
do;
call missing(var);
end;
run;

proc print data=want;
run;

HTH
Patrick

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