DATA Step, Macro, Functions and more

vartype

Reply
Super Contributor
Posts: 673

vartype

The zipcode we gives us problems.we get it as numeric sometimes and as character sometimes.eventually we will be needing it as character.if the leading zeros are not there then append zeros.
something like this:

data Healthpartners_v1;
set Healthpartners;
if vartype(Healthpartners,zip)='N' then do;
zip1=strip(put(zip,z5.));
drop zip;
end;
rename zip1=zip;
run;
Frequent Contributor
Posts: 102

Re: vartype

Statements like DROP and RENAME are compile time statements. Even though this code has them inside conditional bocks, they are still always executed. I would approach this with a macro. You are also not implementing vartype correctly. The dataset cannot be refered to by name, it must referenced via an open statement, and the variable must be reference via a VARNUM statement. Here is a simple way to aproach it.
-----------------------------------------------------------------
data Healthpartners;
x = 1;
zip = 98501;
run;

%macro changeZip;
%let dsid = %sysfunc(open(Healthpartners,is));
%if %sysfunc(vartype(&dsid,%sysfunc(varnum(&dsid,zip)))) = N %then %do;
%let rc = %sysfunc(close(&dsid));
data Healthpartners(drop = zipUnkn);
set Healthpartners(rename = (zip = zipUnkn));
length zip $5;
zip=strip(put(zipUnkn,z5.));
run;
%end;
%else %let rc = %sysfunc(close(&dsid));
%mend;
%changeZip;
------------------------------------------------------------------------------
Super Contributor
Super Contributor
Posts: 3,174

Re: vartype

Posted in reply to CurtisMack
I suppose the presumption here is that there are no "mail codes" from outside the U. S. in your data, for example Canadian mail codes which have legitimate alpha characters?

Scott Barry
SBBWorks, Inc.
Super Contributor
Posts: 673

Re: vartype

Posted in reply to CurtisMack
If there are more than one conditions to check, I tried this one and it seems there is some problem with mg.usually mg is numeric.but if we get it as character:


data Healthpartners12;
x = 1;
zip = 98501;
mg='60.01';
run;

%macro changeZip;
%let dsid = %sysfunc(open(Healthpartners12,is));
%if %sysfunc(vartype(&dsid,%sysfunc(varnum(&dsid,zip)))) = N %then %do;
%let rc = %sysfunc(close(&dsid));
data Healthpartners12(drop = zipUnkn);
set Healthpartners12(rename = (zip = zipUnkn));
length zip $5;
zip=strip(put(zipUnkn,z5.));
run;
%end;
%else %let rc = %sysfunc(close(&dsid));

%if %sysfunc(vartype(&dsid,%sysfunc(varnum(&dsid,mg)))) = C %then %do;
%let rc = %sysfunc(close(&dsid));
data Healthpartners12(drop = mgUnkn);
set Healthpartners12(rename = (mg = mgUnkn));
length mg 8;
mg=input(mgUnkn,??best12.));
run;
%end;
%else %let rc = %sysfunc(close(&dsid));


%mend;
%changeZip;
Frequent Contributor
Posts: 102

Re: vartype

The line
-------------------------------
%let dsid = %sysfunc(open(Healthpartners12,is));
--------------------------------
Opens the dataset and sets the macro variable dsid to a numeric value referencing that open file.
The lines
--------------------------------
%let rc = %sysfunc(close(&dsid));
----------------------------------
Close that open file makeing the value of dsid unusable. What you need to do is either ad another open statement before you start the part that checks mg, or move the close statments so that they occur after you are done with the dsid reference. The trick is that it must be closed before you execute the dataset because the open statement locks the dataset. I think the simpliest approach would be to test the two variables and save the results in macro varaibles, then close the open dataset before starting to write the DATA step. The added advantage is that both conversions can be handled in a single datastep. Something like this.
---------------------------------------------
data Healthpartners12;
x = 1;
zip = '98501';
mg=60.01;
run;

%macro changeZip;
%let dsid = %sysfunc(open(Healthpartners12,is));
%let ChangeZip = False;
%let ChangeMG = False;
%if %sysfunc(vartype(&dsid,%sysfunc(varnum(&dsid,zip)))) = N %then %let ChangeZip = True;
%if %sysfunc(vartype(&dsid,%sysfunc(varnum(&dsid,mg)))) = C %then %let ChangeMG = True;
%let rc = %sysfunc(close(&dsid));

%if &ChangeZip = True or &ChangeMG = True %then %do;
data Healthpartners12;
set Healthpartners12(%if &ChangeZip = True %then %do;
rename = (ZIP = ZIpUnkn)
%end;
%if &ChangeMG = True %then %do;
rename = (mg = mgUnkn)
%end;
);
%if &ChangeZip = True %then %do;
drop = zipUnkn;
length zip $5;
zip=strip(put(zipUnkn,z5.));
%end;
%if &ChangeMG = True %then %do;
drop = mgUnkn;
length mg 8;
mg=input(mgUnkn,??best12.);
%end;
run;
%end;

%mend;
options mprint;
%changeZip;
------------------------------------------- Message was edited by: Curtis Mack
Super Contributor
Posts: 673

Re: vartype

Posted in reply to CurtisMack
Thanks Curtis.
I will apply this for other analysis variables.
Super Contributor
Posts: 673

Re: vartype

Posted in reply to CurtisMack
well..
if the zip is character and if the leading zeros are missing, we will miss that under the condition?
data x;
zip='8912';
run;
actual zip is 08912
Frequent Contributor
Posts: 102

Re: vartype

That wasn't what you were talking about. That is easily fixed with an approach similar to what Patrick already suggested. In some data step add a line like:
--------------------------------------------
zip=put(input(zip,5.),z5.);
------------------------------------------
Curtis
Respected Advisor
Posts: 4,173

Re: vartype

The following code works for both character and numeric zip vars.

In case of a character zip var you would see the following log message:
NOTE: Character values have been converted to numeric values...

data have;
zip='25';
/*zip=25;*/
run;

data want(drop=inzip);
set have(rename=(zip=inzip));
if not missing(inzip) then
zip=put(sum(inzip,0),z5.);
run; added handling for missings


Message was edited by: Patrick
Frequent Contributor
Posts: 102

Re: vartype

This is a good approach and it is much easier to read. The only advantage to my macro approach is that the datastep only runs if the conversion is needed.
Ask a Question
Discussion stats
  • 9 replies
  • 432 views
  • 0 likes
  • 4 in conversation