BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
DoumbiaS
Quartz | Level 8

Heey,

Is it possible using sas proc fcmp, to get a 2 dimensional output like this:

 

do i = 1 to n;
do j = 1 to p; mat[i,j]= i**j; end; end; return(mat); endsub;

It can be done using array statements in a simple data step, but proc fcmp allows portable fonctions.

 

Regards

 

1 ACCEPTED SOLUTION

Accepted Solutions
KachiM
Rhodochrosite | Level 12

You need to pass a two-dimensional _temporary_ array, n by p which at the time of compilation, will be be filled with missing values by default. Pass the array, n and p to Proc FCMP SUBROUTINE with OUTARG option to return the filled array. But there are painless ways of using FCMP to dynamically allocate arrays and write out the filled array as a data set. Your requirement is not sufficient to provide such easy ways.

 

Here is one indirect way:

proc fcmp outlib = work.cmpds.lib;
   subroutine fillmat(mat[*,*], n, p);
   outargs mat;
   do i = 1 to n;   
      do j = 1 to p;
         mat[i,j]= i**j;
      end;
   end;
endsub;
quit;

options cmplib = work.cmpds;
%let n = 4;
%let p = 3; data _null_; array k[&n,&p] _temporary_; call fillmat(k,&n,&p); do i = 1 to &n; do j = 1 to &p; put k[i,j] =; end; end; run;

.

View solution in original post

6 REPLIES 6
Kurt_Bremser
Super User

User-defined functions can only return one value of type numeric or character. A return of a compound value (array or matrix) is not possible, AFAIK.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Personally I would avoid fcmp as its just obfuscation to the nth degree.  

These are compiled functions and so can have any number of paramters, but only one return type and array is not a type but a collection.  From what you posted there, what would be the benefit of hiding that code?  It seems to be a simple do loop and array statement, so just use plain base SAS code, or if you really have to, put it in a macro.

DoumbiaS
Quartz | Level 8

Yes. As i said previously, it can be easily done using a data step with array.

 

data want;
array x{5};
do j= 1 to 3;
do i= 1 to 5; x[i]= i**j; end; output; end; run;

 

But such i want to handle it with many kind of data and return an output data...

 

Regards

RW9
Diamond | Level 26 RW9
Diamond | Level 26

If you want to have code that changes depenging on parameters and data then you use Macro Language.  This is a code generation facililty which generates code based on these factors.  

Compiled functions are there to do very specific small data manipulations, not to do large data manipulation tasks.

Not sure what you mean by "but proc fcmp allows portable fonctions"

SAS code is all text files, Macro is text files or compiled macro libraries just like fcmp.  For portability plain text files are ideal as they can be copied to any system and used in many ways.  FCMP and compiled macros hide the code and not as compatible across systems, protected ones even less so.

 

As you are creating general code, you would need to have more description, something like a functional design specifications which shows inputs/outputs etc.  From what you have posted code-wise, what do you want to be general, is it just the j/i variables if so:

%macro Do_Calc (multiplier=,elements=);
data want;
array x{&elements.};
do j= 1 to &multiplier.;
do i= 1 to &elements.;
x[i]= i**j;
end;
output;
end;
run;
%mend Do_Calc;

%Do_Calc (multiplier=3,elements=5);

 

KachiM
Rhodochrosite | Level 12

You need to pass a two-dimensional _temporary_ array, n by p which at the time of compilation, will be be filled with missing values by default. Pass the array, n and p to Proc FCMP SUBROUTINE with OUTARG option to return the filled array. But there are painless ways of using FCMP to dynamically allocate arrays and write out the filled array as a data set. Your requirement is not sufficient to provide such easy ways.

 

Here is one indirect way:

proc fcmp outlib = work.cmpds.lib;
   subroutine fillmat(mat[*,*], n, p);
   outargs mat;
   do i = 1 to n;   
      do j = 1 to p;
         mat[i,j]= i**j;
      end;
   end;
endsub;
quit;

options cmplib = work.cmpds;
%let n = 4;
%let p = 3; data _null_; array k[&n,&p] _temporary_; call fillmat(k,&n,&p); do i = 1 to &n; do j = 1 to &p; put k[i,j] =; end; end; run;

.

DoumbiaS
Quartz | Level 8

Yes absolutly, i don't say enough... Thanks to everyone. Your ideas are brilliant

 

Best Regards

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 891 views
  • 3 likes
  • 4 in conversation