BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
sfffdg
Obsidian | Level 7

Hi,

 

can the below code be written in small and efficient way.basically can we eliminate the repetitive code.

 

 

 

data test2;
set test;

if freq='M' then
do;
date1=canceldate;
days2=intnx('month',date1,1)-intnx('month',date1,0);
if days < days2 then
do;
prem=round(days/days2*prem1,0.01);
calc=round(days/days2*calc1,0.01);
end;

end;
else if freq='H' then
do;
date1=canceldate;
days2=intnx('month',date1,6)-intnx('month',date1,0);
if days < days2 then
do;
prem=round(days/days2*prem1,0.01);
calc=round(days/days2*calc1,0.01);
end;

end;

else if freq='Q' then
do;
date1=canceldate;
days2=intnx('month',date1,3)-intnx('month',date1,0);
if days < days2 then
do;
prem=round(days/days2*prem1,0.01);
calc=round(days/days2*calc1,0.01);
end;

end;

else if freq='F' then
do;
date1=canceldate;
days2=intnx('week',date1,2)-intnx('week',date1,0);
if days < days2 then
do;
prem=round(days/days2*prem1,0.01);
calc=round(days/days2*calc1,0.01);
end;

end;

run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
mkeintz
PROC Star

You have 'week' as the designated interval for FREQ='F', and month for the other listed FREQ values.  So you have to change two parameters in the intnx function.

 

Also, there is no need within the code you submitted to generate date1, since canceldate can be used in the function calls:

 

Below is untested in the absence of sample data:

 

data test2 (drop=_:);
  set test;

  if freq in ('M','H','Q','F') then do;
    _parm2=index('MFQ..H',freq); /* M->1, F->2, Q->3, H->6 */
    _parm1='month';
    if freq='F' then _parm1='week';
  end;
  days2=intnx(_parm1,canceldate,_parm2,0);
  if days < days2 then do;
    prem=round(days/days2*prem1,0.01);
    calc=round(days/days2*calc1,0.01);
  end;
run;

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26

It looks as if the only thing that is changing is the 3rd argument of INTNX. (By the way, you should just come out and say that — tell us what you know — rather than expecting someone to figure that out and possibly get it wrong ... did I miss any other areas of code that is changing?)

 

 

data test2;
    set test;
    if freq='M' then parm=1;
    else if freq='H' then parm=6;
    else if freq='Q' then parm=3;
    else if freq='F' then parm=2;
    date1=canceldate;
    days2=intnx('month',date1,parm)-intnx('month',date1,0);
    if days < days2 then do;
        prem=round(days/days2*prem1,0.01);
        calc=round(days/days2*calc1,0.01);
    end;
run;

 

 

--
Paige Miller
Astounding
PROC Star

One issue in producing an equivalent program is this.  Is FREQ guaranteed to always be "M", "J", "Q", or "F"?  If so, @PaigeMiller 's suggestion is ideal.  If not (for example, if FREQ is sometimes missing),  you might want to modify it slightly:

data test2;
    set test;
    if freq='M' then parm=1;
    else if freq='H' then parm=6;
    else if freq='Q' then parm=3;
    else if freq='F' then parm=2;
   if freq in ('M', 'H', 'Q', 'F') then do;
     date1=canceldate;
     days2=intnx('month',date1,parm)-intnx('month',date1,0);
     if days < days2 then do;
        prem=round(days/days2*prem1,0.01);
        calc=round(days/days2*calc1,0.01);
     end;
   end;
run;

 

andreas_lds
Jade | Level 19

Not sure if this performs better than the suggested solutions (code is not tested):

proc format;
  invalue freq2num
    'M' = 1
    'H' = 6
    'Q' = 3
    'F' = 2
    other = .;
run;

data want;
  set have;
  date1=canceldate;
  days2=intnx('month',date1,input(freq, freq2num.)) - intnx('month',date1,0);

  if days < days2 then do;
    prem=round(days/days2*prem1,0.01);
    calc=round(days/days2*calc1,0.01);
  end;
run;
mkeintz
PROC Star

You have 'week' as the designated interval for FREQ='F', and month for the other listed FREQ values.  So you have to change two parameters in the intnx function.

 

Also, there is no need within the code you submitted to generate date1, since canceldate can be used in the function calls:

 

Below is untested in the absence of sample data:

 

data test2 (drop=_:);
  set test;

  if freq in ('M','H','Q','F') then do;
    _parm2=index('MFQ..H',freq); /* M->1, F->2, Q->3, H->6 */
    _parm1='month';
    if freq='F' then _parm1='week';
  end;
  days2=intnx(_parm1,canceldate,_parm2,0);
  if days < days2 then do;
    prem=round(days/days2*prem1,0.01);
    calc=round(days/days2*calc1,0.01);
  end;
run;

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
mkeintz
PROC Star

Editted comment.  Just realized that I submitted this response twice, so I'm striking out the entire content below:

 

It looks like you want WEEK interval for FREQ=-'F' and MONTH for the others.  So you have to modify two parameters of the INTNX function.

 

Also there is no apparent need for the DATE1 variable in you code, since CANCELDATE is identical.

 

The code below is untested:

 

data test2 (drop=_:);
  set test;

  if freq in ('M','H','Q','F') then do;
    _parm2=index('MFQ..H',freq); /* M->1, F->2, Q->3, H->6 */
    _parm1='month';
    if freq='F' then _parm1='week';
  end;
  days2=intnx(_parm1,canceldate,_parm2,0);
  if days < days2 then do;
    prem=round(days/days2*prem1,0.01);
    calc=round(days/days2*calc1,0.01);
  end;
run;

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

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
  • 5 replies
  • 820 views
  • 2 likes
  • 5 in conversation