Subscribe Bookmark RSS Feed

make custom functions usable in formula's

ray3

Community Trekker

Joined:

Jun 23, 2011

Hi All,

Is there a way to register a script containing functions to make them usable in column formulas? 

For example, if a wrote a script with a function hex2binary({str}) that converts a hex number into a string of its binary equivalent, and I wanted to be able to call this function in a formula similar to one of the built in JSL formula, is that possible?

Thanks

Ray

1 ACCEPTED SOLUTION

Accepted Solutions
epf_novozymes_c

Community Member

Joined:

Feb 4, 2016

Solution

Hi Ray3, Jeff, MS

Some time ago, but I actually  think I figured out how to do this!

I also tried the "include" method described by MS, and it works but is incredibly slow. 

However, I was also able to make the add-in method  work by creating the add-in with my function, and then calling it from the formula editor by

global:myfunc()

More specifically, I made this function (It's R-based, and actually just returns the square root of the argument, but I suppose it doesn't matter here :-)

myRoot = Function({x},

R Init( );

R send (x);

R Submit("

  y <- sqrt(x)

");

a = R Get (y);

R Term( );

Return(a);

);

And then I could add this formula for a new column:

global:myRoot(:Column 1)

Cheers,


Esben

5 REPLIES
ms

Super User

Joined:

Jun 23, 2011

I am not aware of a way to register custom functions globally that works in column formulas. However, there is a way, perhaps not very convenient, to call a function locally from a saved jsl-file.

Let's say you have saved a script with only this function. The file is named "plus_one" (or whatever).

plus_one=function({X}, X+1);

To call this function within a column formula use local() and include() as below:

Local( plus_one,

  Include( "path/plus_one.jsl" );

  plus_one( :Column );

)

Where path is the path to the saved jsl-file and :Column is the column you apply the formula to. Include() parses and evaluates the jsl code in the file (however the file is not opened) and without the local context you will get an error.

It is not beautyful but it works and may be useful if the function is very complex and is reused often.

Actually it just occurred to me that it should be possible to collect all my custom formula in a single file and use a start-up script to set the path-variable. Then they would be easier to implement "globally". And any changes in the stored functions would be translated to all your datatables without the need to edit each column that have a user-defined function. I have not tested this idea, but it is an intriguing prospective. May be a RAM-hungry approach though.

Jeff_Perkinson

Community Manager

Joined:

Jun 23, 2011

Hi Ray,

There's no way to get the function to appear in the function browser in the Formula Editor, but user defined functions can be used in formulas by double clicking on a formula element and typing the function call.

To ensure that your functions are defined in every JMP session you've got a couple of options.

1) You can put your function declaration in the JMPStart.JSL file.

2) You can make an add-in that has no menus and no functionality beyond declaring these functions. Just put the function declarations in the addinload.jsl file. Any copy of JMP that has that add-in installed will have those functions available.

I hope that helps.

-Jeff

-Jeff
ray3

Community Trekker

Joined:

Jun 23, 2011

Hi Jeff, MS,

Thanks for the hints.  I tried both suggestions:

Using Local(Include()) functions worked, but was fairly slow for my data set (which is roughly 20,000 lines long) as each time it calculates the formula it is opening the included file.

I also tried Jeff's suggestion, and added the function to the JMPStart.jsl.  The function shows up in a the global symbols list, and I am able to call it from other scripts without problem in a session.  However if I call the function from a column formula I get a "name unresolved" error.  Is there anything special I need to do for scoping to get the column formula to recognize the function?

Thanks!

Ray

epf_novozymes_c

Community Member

Joined:

Feb 4, 2016

Solution

Hi Ray3, Jeff, MS

Some time ago, but I actually  think I figured out how to do this!

I also tried the "include" method described by MS, and it works but is incredibly slow. 

However, I was also able to make the add-in method  work by creating the add-in with my function, and then calling it from the formula editor by

global:myfunc()

More specifically, I made this function (It's R-based, and actually just returns the square root of the argument, but I suppose it doesn't matter here :-)

myRoot = Function({x},

R Init( );

R send (x);

R Submit("

  y <- sqrt(x)

");

a = R Get (y);

R Term( );

Return(a);

);

And then I could add this formula for a new column:

global:myRoot(:Column 1)

Cheers,


Esben

ian_jmp

Staff

Joined:

Jun 23, 2011

Looks like you are there already. But, for another example you can reverse engineer the add-in at:

https://community.jmp.com/docs/DOC-7528