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
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:
1 | options cmplib=work.funcs; |
2
3 | proc fcmp outlib=work.funcs.temp; |
WARNING: No CMP or C functions found in library work.funcs.
4 | function summation (b |
5 | total = 0; |
6 | do i = 1 to dim(b); |
7 | total = total + b; |
8 | end; |
9 | return(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
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,
I don't know about all that. Are you sure you need a function? Maybe a macro would be good enough.
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
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:
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,
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: