DATA Step, Macro, Functions and more

proc fcmp function with variable arguments does not work

Reply
Occasional Contributor TD
Occasional Contributor
Posts: 13

proc fcmp function with variable arguments does not work

Hi,

I have issue with Base SAS(R) 9.3 Procedures Guide, Second Edition example (fixed to run without syntax error). I'm using sas 9.3.

Code:

options cmplib=work.funcs;

proc fcmp outlib=work.funcs.temp;

function summation (b

  • ) varargs;
  •     total = 0;

        do i = 1 to dim(b);

            total = total + b;

        end;

    return(total);

    endsub;

    quit;

    options cmplib=(work.funcs);

    data _null_;

        sum=summation(1,2,3,4,5);

        put sum=;

    run;

    Log:

    1options cmplib=work.funcs;

    2

    3proc fcmp outlib=work.funcs.temp;

    WARNING: No CMP or C functions found in library work.funcs.

    4function summation (b
  • ) varargs;
  • 5    total = 0;
    6    do i = 1 to dim(b);
    7        total = total + b;
    8    end;
    9return(total);

    10   endsub;

    11   quit;

    NOTE: Function summation saved to work.funcs.temp.

    NOTE: PROCEDURE FCMP used (Total process time):

      real time       0.03 seconds
      user cpu time   0.00 seconds
      system cpu time 0.03 seconds
      memory          3787.98k
      OS Memory       10436.00k
      Timestamp       01/28/2014 04:59:42 PM

    12

    13   options cmplib=(work.funcs);

    14

    15   data _null_;

    16   sum=summation(1,2,3,4,5);
    16   sum=summation(1,2,3,4,5);
             ---------
             72

    ERROR 72-185: The summation function call has too many arguments.

    16   sum=summation(1,2,3,4,5);
             ---------
             707

    ERROR 707-185: Expecting array for argument 1 of the summation subroutine call.

    17   put sum=;

    18   run;

    NOTE: The SAS System stopped processing this step because of errors.

    NOTE: DATA statement used (Total process time):

      real time       0.01 seconds
      user cpu time   0.00 seconds
      system cpu time 0.01 seconds
      memory          2104.40k
      OS Memory       10436.00k
      Timestamp       01/28/2014 04:59:42 PM

    Anyone seen this before? Anyone has a working function example with variable number of arguments?

    Thanks

    Respected Advisor
    Posts: 3,799

    Re: proc fcmp function with variable arguments does not work

    proc fcmp outlib=work.funcs.temp;
       function summation (b
  • )
  • varargs;
          total =
    0;
         
    do i = 1 to dim(b);
             total = total + b;
            
    end;
         
    return(total);
          endsub;
      
    quit;


    options cmplib=(work.funcs);


    data _null_;
      
    array a[5_temporary_ (1:5);
       sum=summation(a);
       sum2=sum(of a
  • );
      
  • put sum= sum2=;
       run;
    Occasional Contributor TD
    Occasional Contributor
    Posts: 13

    Re: proc fcmp function with variable arguments does not work

    Posted in reply to data_null__

    This is helpful, but not as per SAS documentation. I want to use user defined function in proc sql where statement, so the temp array is not a solution. In addition, I don't want to manually define number of arguments (again, temporary array limitation). But the main problem is required use of datastep array. I want to call a function just with arguments so I could use the function in proc sql.

    Cheers,

    Respected Advisor
    Posts: 3,799

    Re: proc fcmp function with variable arguments does not work

    I don't know about all that.  Are you sure you need a function?  Maybe a macro would be good enough.

    Trusted Advisor
    Posts: 1,301

    Re: proc fcmp function with variable arguments does not work

    Varargs works as you suggest within PROC FCMP, but to use a function in this syntax outside of FCMP itself you need to assign the variable argument list to a temporary array.

    So, with the example from the documentation as you have put here:

    options cmplib=sasuser.funcs;

    proc fcmp outlib=sasuser.funcs.temp;

    function summation (b

  • ) varargs;
  •   total = 0;

      do i = 1 to dim(b);

      total = total + b;

      end;

    return(total);

    endsub;

    sum=summation(1,2,3,4,5);

      put sum=;

    run;

    You see the call to summation is within FCMP, so this syntax works.

    As you have now figured out, this is not well documented.

    Adding a function of this type for use in PROC SQL would add significant and unnecessary overhead to the calculation process.

    For this exact example, nothing would prevent you from using the standard sum function, but I assume you would be wanting to calculate something else.

    proc sql;

    select height,weight,sum(height,weight) as tot from sashelp.class;

    quit;

    With a better example of what it is you are aiming to accomplish, I would be fairly sure another solution could be offered that does not rely on FCMP.

    You can find an example of this with code very similar to that provided by DN on the following usage note:

    41754 - Working with ARRAYs in PROC FCMP

    Occasional Contributor TD
    Occasional Contributor
    Posts: 13

    Re: proc fcmp function with variable arguments does not work

    Hi

    Yes, I saw later that the example is actually working inside proc fcmp. I assumed that I could actually define a user function similar to cat(), where number of arguments is not defined.

    The problem is already solved with macro. I'll share a problem, so maybe someone can share their neat solution to it.

    Problem:

    For the undefined number of words, check if any of the words are actually in the string. I.e. to simulate such statement:

    indexw(source, 'string1') or indexw(source, 'string2') or .. or indexw(source, 'stringX')

    stringN can be any possible non-missing string, including single/multiple white space.

    The function I was attempting to write was just to make code look cleaner and easier to maintain when search strings are added or removed.

    Thanks for all the trouble.

    Just by writing this I had a thought that regular expressions could also solve this without a macro:

    prxmatch('/\b(string1|string2|...|stringX)\b/')

    (Please be aware, regexp not actually checked, just something from my head. Regexp tend to become write-only in long term and it's difficult to maintain)

    Thanks,

    Ask a Question
    Discussion stats
    • 5 replies
    • 1077 views
    • 6 likes
    • 3 in conversation