BookmarkSubscribeRSS Feed
Elaine_
Calcite | Level 5

Dears, I want to deliver value of macro variable within one data step,  there are two datasets named DS_SUMMARY and DS_SURVIVAL, each one have three time related variables which I need to transform to Character type to compare the value.  I wonder if resolve() function could deal with this. The problem is  when it comes to the code "if dsvar='N' then do.....else if dsvar='C' then do...;", it can not jump into the right  %iso8601 section by execute two conditions one by one. So I wonder how could this be resolved?

followed by data:

data WORK.CONTENT;
infile datalines ;
input LIBNAME: $3. MEMNAME: $22. NAME: $12. TYPE: $4. LENGTH: 8.;
label LIBNAME="Library Name" MEMNAME="Member Name" NAME="Column Name" TYPE="Column Type" LENGTH="Column Length";
datalines;
RAW DS_SUMMARY EXLSDAT char 200
RAW DS_SUMMARY UNBLNDTC char 200
RAW DS_SUMMARY PDDAT num 8
RAW DS_SURVIVAL DTHDAT char 200
RAW DS_SURVIVAL LIVEDAT num 8
RAW DS_SURVIVAL LOSTDAT num 8
;
run;

%macro find(); proc sql noprint; select distinct memname into: alldataset separated by "|" from content; select count(distinct memname) into: ndata from content; quit; %put &sqlobs; %do i=1 %to &ndata; %let rawdata=%scan(&alldataset, &i, |); proc sql noprint; select name into: datlist separated by '| ' from content where memname="&rawdata"; select strip(name)||%trim("_c") into: vardtc separated by ' ' from content where memname="&rawdata"; quit; %let datnum=%eval(%sysfunc(count("&datlist",%str(|)))+1); data _test&i; set raw.&rawdata; length x&i rawdata&i $50.; rawdata&i="&rawdata"; usubjid=catx("-",studyid,siteid,substr(subjid,3,3)); %do j=1 %to &datnum; %let datdone=%scan(&datlist, &j, |); call symputx('type',vtype(&datdone)); dsvar=resolve('&type'); if dsvar='N' then do; %iso8601(dtin=put(&datdone,yymmdd10.),dtout=&datdone._c); end; else if dsvar='C' then do; %iso8601(dtin=&datdone,dtout=&datdone._c); end; &datdone._c=substr(&datdone._c,1,10); %end;
run;

%end; %mend;

 

Problem:

1."if dsvar='N' then do.....else if dsvar='C' then do...;", it can not jump into the right  %iso8601 section by execute two conditions one by one. 

2. put(UNBLNDTC,yymmdd10.)
                                ---------
                                   484

6 REPLIES 6
ChrisNZ
Tourmaline | Level 20

Why don't you start the %iso8601 macro with something like:

%* If the parameter value is a SAS date, then format it ;

%if %length(&datdone)=5 %then %let datdone=%sysfunc(putn(&datdone,yymmdd10.));

instead of trying the address the problem before calling the macro?

 

Aside: Is it not a data quality issue if the variable type is unknown?

Elaine_
Calcite | Level 5

Because %iso8601 is a standard macro used within Cor.  

it's true those data are messed up and type need to be deal with...

ChrisNZ
Tourmaline | Level 20

1. Maybe the data should be cleaned rather than add convoluted logic to address the flaws.

 

2. Short of that the macro should be improved to accept the different possible values.

 

3. I am unsure what this code is trying to achieve, and I have a suspicion it could be coded in a simpler fashion, but as a third option, this should do what you expect:

  NUMVAL=input(cats(&datdone),10.);
  if DSVAR='N' then do;
    %iso8601(dtin=put(NUMVAL,yymmdd10.),dtout=&datdone._c);
  end;
  else if DSVAR='C' then do;
    %iso8601(dtin=NUMVAL,dtout=&datdone._c);
  end;           

 

 

Tom
Super User Tom
Super User

What is this %ISO8601 macro doing?

 

PS: Your SQL steps are working too hard. SAS can count for you.

select distinct memname into :alldataset separated by '|' from content;
%let ndata=&sqlobs;
...
select name
     , cats(name,'_C')
into :datlist separated by '|' 
   , :vardtc separated by ' ' 
from content 
where memname="&rawdata"
;
%let datnum=&sqlobs;
Elaine_
Calcite | Level 5

Thank you for tips! %iso8601 is a common character format which need to transform all numeric to character data type to use this macro. 捕获.PNG

 

Tom
Super User Tom
Super User

But WHAT is that macro.

418  data _null_;
419   %iso8601;
      -
      180
WARNING: Apparent invocation of macro ISO8601 not resolved.
ERROR 180-322: Statement is not valid or it is used out of proper order.

420  run;

How it works makes a difference in how you can USE it.

If you don't know how it works then write a little example data step that uses and it run it with MPRINT option turned on. Show use the lines in the SAS log that the MPRINT option generates.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 820 views
  • 0 likes
  • 3 in conversation