Release 8
Scripting Guide
“The real voyage of discovery consists not in seeking new landscapes, but in having new eyes.” Marcel Proust
JMP, A Business Unit of SAS SAS Campus Drive Cary, NC 27513
The correct bibliographic citation for this manual is as follows: SAS Institute Inc. 2008. JMP® 8 Scripting Guide. Cary, NC: SAS Institute Inc.
JMP® 8 Scripting Guide
Copyright © 2008, SAS Institute Inc., Cary, NC, USA
ISBN 978-1-59994-922-2
All rights reserved. Produced in the United States of America.
For a hard-copy book: No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, or otherwise, without the prior written permission of the publisher, SAS Institute Inc.
For a Web download or e-book: Your use of this publication shall be governed by the terms established by the vendor at the time you acquire this publication.
U.S. Government Restricted Rights Notice: Use, duplication, or disclosure of this software and related documentation by the U.S. government is subject to the Agreement with SAS Institute and the restrictions set forth in FAR 52.227-19, Commercial Computer Software-Restricted Rights (June 1987). SAS Institute Inc., SAS Campus Drive, Cary, North Carolina 27513.
1st printing, October 2008
SAS® Publishing provides a complete selection of books and electronic products to help customers use SAS software to its fullest potential. For more information about our e-books, e-learning products, CDs, and hard- copy books, visit the SAS Publishing Web site at support.sas.com/publishing or call 1-800-727-3228. SAS® and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. ® indicates USA registration.
Other brand and product names are registered trademarks or trademarks of their respective companies. Table of Contents JMP Scripting Guide
1 Introducing JSL Tutorials and Demonstrations ...... 1 Hello, World ...... 3 Modify the script ...... 5 Save your script ...... 6 Save your log ...... 7 Saving and sharing your work ...... 7 Capturing scripts for data tables ...... 7 Capturing scripts for analyses ...... 8 A general method for creating scripts ...... 9 Use JMP interactively to learn scripting ...... 10 Samples of JSL Scripts ...... 11 Data table programming ...... 11 Customized analyses ...... 13 Custom displays ...... 18 Matrix algebra with JSL ...... 19 Scripting graphs ...... 23 Scripting instructional simulations ...... 25 2 JSL Building Blocks Learn the Basic Components of JSL ...... 29 First JSL Script ...... 31 The JSL Language ...... 31 Lexical rules of the language ...... 32 Data elements ...... 37 Operators ...... 38 Context: meaning is local ...... 40 Programming vs. scripting ...... 40 Data table context ...... 41 Scoping operators ...... 42 Graph context ...... 42 Name resolution ...... 42 Name-binding rules ...... 43 ii
Frequently-asked questions ...... 45 Function resolution rules ...... 46 Using the Script Editor and Debugger ...... 46 The Script Editor ...... 47 The JSL Debugger ...... 52 Help with JSL ...... 54 JSL Browsers ...... 54 Show Commands ...... 55 Show Properties ...... 56 3 JSL Operators The basic functions in JSL ...... 59 Numeric Functions ...... 61 Arithmetic operators ...... 61 Assignment operators ...... 61 Constants ...... 62 Additional numeric functions ...... 62 Transcendental functions ...... 63 Trigonometric Functions ...... 65 Random Functions ...... 66 Character Functions ...... 67 Comparison and Logical Operators ...... 74 Comparison operators ...... 74 Logical operators ...... 76 Special cases ...... 76 Missing values ...... 77 Missing character values ...... 78 Short-circuiting behavior ...... 78 Date/Time Operators ...... 79 Constructing dates ...... 79 Extracting parts of dates ...... 79 Arithmetic on dates ...... 80 Converting date/time units ...... 80 Y2K-ready date handling ...... 80 Date/time notation ...... 81 Currency ...... 85 Inquiry Functions ...... 85 Functions that communicate with users ...... 86 Writing to the log ...... 87 Send information to the user ...... 87 Contents iii 96 129 . . . . 96 . . . . 98 ...... 100 ...... 103 ...... 113 ...... 124 ...... 122 ...... 115 ...... 100 ...... 93 ...... 118 ...... 122 ...... 93 ...... 96 ...... 123 ...... 97 ...... 107 ...... 103 ...... 125 ...... 101 ...... 102 ...... 91 ...... 115 ...... 99 ...... 94 ...... 101 ...... 107 ...... 96 ...... 98 ...... 101 ...... 93 ...... 94 ...... 94 ...... 101 ...... 94 ...... 97 Getting a dataGetting tableobject messages and Objects Naming, saving, and saving, printing Naming, Journal and Layout Journal andCreating deleting columns values Accessing Summarize Glue First Example For While Summation Product Break and Continue If Match Choose Interpolate Step Wait Schedule Variables Global Local variables Lists Matrices Associative Arrays Associative Messages for data tables Messages Data table basics Create, open, and manipulate data tables data manipulate open, and Create, Gluing expressions together expressions Gluing Script Control Script Programming Example Iterating Conditional functions Controlling script execution Variables JSL Data Structures 5 Data Tables 4 Functions Programming iv
Working with metadata ...... 131 Commands from the Rows menu ...... 136 Commands from the Tables menu ...... 140 Manipulating columns ...... 145 Setting and getting attributes ...... 148 Row State operators ...... 154 What are row states? ...... 155 An overview of row state operators ...... 159 Each of the row state operators in detail ...... 163 Optional: the numbers behind row states ...... 169 Calculations ...... 170 Pre-evaluated statistics ...... 170 Calculator formulas ...... 172 6 Scripting Platforms Create, repeat, and modify analyses ...... 173 Scripting analysis platforms ...... 175 Launching platforms interactively and obtaining the equivalent script ...... 175 Sending script commands to a live analysis ...... 182 Launching platforms ...... 186 Objects within analysis objects ...... 187 General messages for platform windows ...... 187 Scripting specific platforms ...... 190 7 Display Trees Create and use dialogs and results windows ...... 225 Manipulating displays ...... 227 Introduction to display boxes ...... 227 DisplayBox object references ...... 230 Sending messages ...... 232 Using the << operator ...... 233 Platform example ...... 234 Syntax Reference ...... 238 Constructing display trees ...... 240 Basics ...... 240 Updating an existing display ...... 242 Controlling Text Wrap ...... 244 Interactive Display Elements ...... 244 Send messages to constructed displays ...... 257 Build your own displays from scratch ...... 258 Construct display boxes containing platforms ...... 259 Contents 1 v 7 6 05 301 . . . . 265 . . 290 . . . 263 . . . 298 ...... 273 ...... 293 ...... 286 ...... 277 ...... 295 ...... 287 ...... 268 ...... 280 ...... 266 ...... 260 ...... 281 ...... 271 ...... 280 ...... 276 ...... 279 ...... 265 ...... 301 ...... 275 ...... 282 ...... 286 ...... 282 ...... 307 ...... 302 ...... 306 ...... 291 ...... 300 ...... 30 ...... 26 ...... 29 ...... 3 ...... 302 ...... 289 ...... 287 Plotting functions Plotting the propertiesGetting of a graphics frame Adding aLegend Adding Construct a custom platform Sheets Making Making changes to graphs Lines Journals Constructing modal dialog boxes General-purpose modal dialogboxes and Column Dialog Details to Dialog common Data column dialog boxes example Advanced Markers Arrows Picture Display Type Pies and Arcs and Ovals Rectangles, Circles, Shapes: Regular and Contours Polygons Shapes: Irregular Adding text Colors Transparency patterns Fill Handle MouseTrap Line types Drag functions Drag Troubleshooting Drawing with pixels Create and edit 2-dimensional plots edit 2-dimensional and Create Adding Scripts to Graphs a LegendAdding to a Graph Scratch From Graphs New Creating Graphing Elements Graphing Drawing lines, arrows, points,lines, and shapes arrows, Drawing Modal Dialogs Modal ScriptingScript the Editor Interactive graphs 8 Graphs Scripting vi
9 Three-Dimensional Scenes Scripting in Three Dimensions ...... 309 About JSL 3-D Scenes ...... 311 JSL 3-D Scene Basics ...... 311 Scene Boxes ...... 311 Setting the Viewing Space ...... 314 Setting Up a Perspective Scene ...... 315 Setting up an Orthographic Scene ...... 316 Changing the View ...... 316 The Translate Command ...... 316 The Rotate Command ...... 316 The Look At Command ...... 318 The ArcBall ...... 319 Graphics Primitives ...... 321 Primitives Example ...... 324 Controlling the Appearance of Primitives ...... 326 Other uses of Begin and End ...... 331 Drawing Spheres, Cylinders, and Disks ...... 331 Construction ...... 331 Lighting ...... 332 Drawing Text ...... 332 Using Text with Rotate and Translate ...... 333 Using the Matrix Stack ...... 334 Lighting and Normals ...... 337 Creating Light Sources ...... 337 Lighting Models ...... 338 Normal Vectors ...... 339 Shading Model ...... 339 Material Properties ...... 340 Alpha Blending ...... 340 Fog ...... 341 Example ...... 341 Bézier Curves ...... 342 One-Dimensional Evaluators ...... 342 Two-Dimensional Evaluators ...... 344 Using the mouse ...... 345 Parameters ...... 347 10 Matrices Matrix algebra in JMP ...... 349 Basics ...... 351 Contents 51 vii 405 404 356 ...... 401 ...... 375 ...... 384 ...... 391 ...... 398 ...... 387 ...... 365 ...... 403 ...... 378 ...... 369 ...... 403 ...... 363 ...... 387 ...... 369 ...... 382 ...... 377 ...... 369 ...... 351 ...... 360 ...... 387 ...... 355 ...... 370 ...... 383 ws and Linux only) ...... 370 ...... 377 ...... 353 ...... 381 ...... 371 ...... 370 ...... 385 ...... 387 ...... 391 ...... 360 ...... 3 ...... Automating JMP through Visual Basic Visual JMP through Automating C++ Visual JMP through Automating SAS Variable Names SAS Variable Server SAS Metadata a Connecting to Making a SAS DATA step Making aSAS DATA Socket-related commands Socket-related for sockets Messages Regression example Regression example ANOVA Definitions Constructing matrices operators Numeric values Manipulating Subscripts Throwing and catching exceptions catching and Throwing Functions Recursion Create a datafeed a datafeed object Create messages a datafeedManage with Matrices and data tables Matrices Matrices and reports Build your own matrix own operators your Build Solving linearsystems Solving construction functions Further and normalizations Decompositions OLE Automation Database access (Windo Database Scheduling actions Working with SAS Complex scripting techniques and additional functions additional and techniques scripting Complex Real-time data capture Concepts Programming Advanced Scripting tools for production settings production for tools Scripting Using sockets in JSL Using Statistical examples Statistical Matrices with the rest of JMP with rest the Matrices Matrix operators Matrix 12 Advanced Concepts 11 Environments Production viii
Includes ...... 405 Loading and Saving Text Files ...... 405 Dynamic Link Libraries (DLLs) (Windows Only) ...... 406 Encryption ...... 407 Encryption and Global Variables ...... 408 XML Parsing Operations ...... 409 Example ...... 409 Pattern Matching and Regular Expressions ...... 412 Patterns and Case ...... 414 Regular Expressions ...... 414 Lists and Expressions ...... 415 Stored expressions ...... 415 Macros ...... 423 Manipulating lists ...... 423 Manipulating expressions ...... 425 Projects ...... 428 Hexadecimal and BLOB Functions ...... 429 Web ...... 431 Additional Numeric Operators ...... 431 Matrices ...... 431 Derivatives ...... 431 Algebraic Manipulations ...... 433 Maximize and Minimize ...... 434 A JSL Syntax Reference Summary of operators, functions, and messages ...... 437 Functions, Variables, and Other Basic Tools ...... 439 Constants ...... 442 Arithmetic and Assignment Operators ...... 442 Numeric Functions ...... 448 Transcendental Functions ...... 449 Trigonometric Functions ...... 452 Random Functions ...... 455 Character/String Functions ...... 458 Comparison/Logical Functions ...... 469 Date/Time Functions ...... 475 General Utility Functions ...... 480 Loop Controls and Conditional Statements ...... 494 Lists ...... 496 Matrices ...... 497 Associative Arrays ...... 510 Contents ix . . . 528 ...... 637 ...... 559 ...... 579 ...... 570 ...... 512 ...... 567 ...... 531 ...... 630 ...... 570 ...... 651 ...... 560 ...... 572 ...... 641 ...... 576 ...... 582 ility Functions ...... 548 ...... 531 ...... 598 ...... 559 ...... 549 ...... Display Boxes Display Dialogs Modal Graphs 3d Scenes Probability Functions Probability Functions Probability Discrete Probab Specialty Log Density Functions Functions Statistical Column Statistics Functions Statistical Additional Syntax Reference Syntax Index JMP Scripting Guide Terms, concepts, and placeholders concepts, Terms, Index Data Tables, Rows, and Columns and Rows, Data Tables, Platforms Windows, Reports, and Dialogs and Reports, Windows, Advanced Concepts Advanced SAS Integration Tools for Production Settings for Production Tools Statistical and Probability Functions and Probability Statistical BGlossary
Credits and Acknowledgments
Origin JMP was developed by SAS Institute Inc., Cary, NC. JMP is not a part of the SAS System, though por- tions of JMP were adapted from routines in the SAS System, particularly for linear algebra and proba- bility calculations. Version 1 of JMP went into production in October, 1989. Credits JMP was conceived and started by John Sall. Design and development were done by John Sall, Chung-Wei Ng, Michael Hecht, Richard Potter, Brian Corcoran, Annie Dudley Zangi, Bradley Jones, Craige Hales, Chris Gotwalt, Paul Nelson, Xan Gregg, Jianfeng Ding, Eric Hill, John Schroedl, Laura Lancaster, Scott McQuiggan, and Peng Liu. In the SAS Institute Technical Support division, Wendy Murphrey and Toby Trott provide technical support and conduct test site administration. Statistical technical support is provided by Craig DeVault, Duane Hayes, Elizabeth Edwards, Kathleen Kiernan, and Tonya Mauldin. Nicole Jones, Jim Borek, Kyoko Keener, Hui Di, Joseph Morgan, Wenjun Bao, Fang Chen, Susan Shao, Hugh Crews, Yusuke Ono and Kelci Miclaus provide ongoing quality assurance. Additional test- ing and technical support is done by Noriki Inoue, Kyoko Takenaka, and Masakazu Okada from SAS Japan. Bob Hickey is the release engineer. The JMP manuals were written by Ann Lehman, Lee Creighton, John Sall, Bradley Jones, Erin Vang, Melanie Drake, and Meredith Blackwelder, with contributions from Annie Dudley Zangi and Brian Corcoran. Creative services and production was done by SAS Publications. Melanie Drake imple- mented the help system. Jon Weisz and Jeff Perkinson provided project management. Also thanks to Lou Valente, Ian Cox, Mark Bailey, and Malcolm Moore for technical advice. Thanks also to Georges Guirguis, Warren Sarle, Gordon Johnston, Duane Hayes, Russell Wolfinger, Randall Tobias, Robert N. Rodriguez, Ying So, Warren Kuhfeld, George MacKensie, Bob Lucas, War- ren Kuhfeld, Mike Leonard, and Padraic Neville for statistical R&D support. Thanks are also due to Doug Melzer, Bryan Wolfe, Vincent DelGobbo, Biff Beers, Russell Gonsalves, Mitchel Soltys, Dave Mackie, and Stephanie Smith, who helped us get started with SAS Foundation Services from JMP. Acknowledgments We owe special gratitude to the people that encouraged us to start JMP, to the alpha and beta testers of JMP, and to the reviewers of the documentation. In particular we thank Michael Benson, Howard Yet- ter (d), Andy Mauromoustakos, Al Best, Stan Young, Robert Muenchen, Lenore Herzenberg, Ramon Leon, Tom Lange, Homer Hegedus, Skip Weed, Michael Emptage, Pat Spagan, Paul Wenz, Mike Bowen, Lori Gates, Georgia Morgan, David Tanaka, Zoe Jewell, Sky Alibhai, David Coleman, Linda xii
Blazek, Michael Friendly, Joe Hockman, Frank Shen, J.H. Goodman, David Iklé, Barry Hembree, Dan Obermiller, Jeff Sweeney, Lynn Vanatta, and Kris Ghosh. Also, we thank Dick DeVeaux, Gray McQuarrie, Robert Stine, George Fraction, Avigdor Cahaner, José Ramirez, Gudmunder Axelsson, Al Fulmer, Cary Tuckfield, Ron Thisted, Nancy McDermott, Veronica Czitrom, Tom Johnson, Cy Wegman, Paul Dwyer, DaRon Huffaker, Kevin Norwood, Mike Thomp- son, Jack Reese, Francois Mainville, and John Wass. We also thank the following individuals for expert advice in their statistical specialties: R. Hocking and P. Spector for advice on effective hypotheses; Robert Mee for screening design generators; Greg Piepel, Peter Goos, J. Stuart Hunter, Dennis Lin, Doug Montgomery, and Chris Nachtsheim for advice on design of experiments; Jason Hsu for advice on multiple comparisons methods (not all of which we were able to incorporate in JMP); Ralph O’Brien for advice on homogeneity of variance tests; Ralph O’Brien and S. Paul Wright for advice on statistical power; Keith Muller for advice in multivariate methods, Harry Martz, Wayne Nelson, Ramon Leon, Dave Trindade, Paul Tobias, and William Q. Meeker for advice on reliability plots; Lijian Yang and J.S. Marron for bivariate smoothing design; George Milliken and Yurii Bulavski for development of mixed models; Will Potts and Cathy Maahs-Fladung for data mining; Clay Thompson for advice on contour plotting algorithms; and Tom Little, Damon Stoddard, Blanton Godfrey, Tim Clapp, and Joe Ficalora for advice in the area of Six Sigma; and Josef Schmee and Alan Bowman for advice on simulation and tolerance design. For sample data, thanks to Patrice Strahle for Pareto examples, the Texas air control board for the pollu- tion data, and David Coleman for the pollen (eureka) data. Translations Erin Vang coordinated localization. Noriki Inoue, Kyoko Takenaka, and Masakazu Okada of SAS Japan were indispensable throughout the project. Special thanks to Professor Toshiro Haga (retired, Sci- ence University of Tokyo) and Professor Hirohiko Asano (Tokyo Metropolitan University for reviewing our Japanese translation. Special thanks to Dr. Fengshan Bai, Dr. Xuan Lu, and Dr. Jianguo Li, profes- sors at Tsinghua University in Beijing, and their assistants Rui Guo, Shan Jiang, Zhicheng Wan, and Qiang Zhao, for reviewing the Simplified Chinese translation. Finally, thanks to all the members of our outstanding translation teams. Past Support Many people were important in the evolution of JMP. Special thanks to David DeLong, Mary Cole, Kristin Nauta, Aaron Walker, Ike Walker, Eric Gjertsen, Dave Tilley, Ruth Lee, Annette Sanders, Tim Christensen, Jeff Polzin, Eric Wasserman, Charles Soper, Wenjie Bao, and Junji Kishimoto. Thanks to SAS Institute quality assurance by Jeanne Martin, Fouad Younan, and Frank Lassiter. Additional testing for Versions 3 and 4 was done by Li Yang, Brenda Sun, Katrina Hauser, and Andrea Ritter. Also thanks to Jenny Kendall, John Hansen, Eddie Routten, David Schlotzhauer, and James Mulherin. Thanks to Steve Shack, Greg Weier, and Maura Stokes for testing JMP Version 1. Thanks for support from Charles Shipp, Harold Gugel (d), Jim Winters, Matthew Lay, Tim Rey, Rubin Gabriel, Brian Ruff, William Lisowski, David Morganstein, Tom Esposito, Susan West, Chris Fehily, Dan Chilko, Jim Shook, Ken Bodner, Rick Blahunka, Dana C. Aultman, and William Fehlner. Technology License Notices The ImageMan DLL is used with permission of Data Techniques, Inc. Credits
- - -
- , xiii
FIT
- OUT MER INDI
OF ,
OF AND
WITH
SOFT PROFITS
TORTIOUS
DISCLAIMS LOSS
ARISING OR CONSEQUEN SPECIAL
, THIS
OR FROM
OF OTHER
ANY
DATA , WARRANTIES OR .
HODGSON WARRANTIES ACTION
FOR
USE
ALL
NEIL INDIRECT OF MERCHANTABILITY
, RESULTING
IMPLIED LIABLE
OF
SOFTWARE
LOSS BE TORTIOUS PERFORMANCE
ALL
NEGLIGENCE , SPECIAL OR
DISCLAIMS THIS
FROM
OF OTHER ANY USE
WHATSOEVER HODGSON
OR WARRANTIES
FOR THE INCLUDING
CONTRACT PACKARD ,
NEIL
OF
RESULTING
WITH
LIABLE IMPLIED
DAMAGES KEITH
BE SHALL PERFORMANCE
ALL NEGLIGENCE SOFTWARE
ANY
ACTION ,
OR
OR AN
EVENT THIS Neil Hodgson
USE
IN
WHATSOEVER PACKARD
CONNECTION TO NO
THE
IN INCLUDING IN
CONTRACT
, , DAMAGES KEITH
OR
OF
WITH
REGARD WHETHER DAMAGES
OF
,
FITNESS SHALL
ANY
OUT SOFTWARE WITH ACTION
AND OR
PROFITS
AN
EVENT THIS
OR IN
CONNECTION CONSEQUENTIAL
ARISING NO
TO
, IN
IN OR .
DAMAGES DATA ,
WARRANTIES ,
OR
REGARD NESS TIAL WHETHER OF ALL CHANTABILITY RECT USE ACTION WARE XRender is Copyright © 2002 Keith Packard. 2002is Copyright © Keith Packard. XRender Scintilla is Copyright 1998-2003Scintilla by
Chapter 1 Introducing JSL Tutorials and Demonstrations
This introduction shows you the basics of JMP Scripting Language (JSL). The chapter starts with a simple, progressive tutorial example to show you where to type a script, how to submit it, and how to modify and save it. The purpose of this tutorial is to give you the basic techniques for working with any script, whether it’s one you write or one you get from someone else. Next is a showcase of examples to demonstrate how scripting might be useful in a variety of settings—for classroom simulations, advanced data manipulations, custom statistics, production lines, etc.
Confusion alert! Throughout this book, special shaded “confusion alerts” like this one call your attention to important concepts that could be unfamiliar or more compli- cated than you might expect—or where JMP might be a little different from other applications. These alerts appear whenever a particularly good example of a potential problem arises in the text, and although you will find them under topics that might not apply to your immediate needs, the ideas presented are always general and impor- tant. Please be sure to take a look even when you’re skipping pages and looking for something else. You can quickly locate these pointers by looking up “confusion alert” in the “Index,” p. 651. Contents Hello, World ...... 3 Modify the script...... 5 Save your script ...... 6 Save your log ...... 7 Saving and sharing your work ...... 7 Capturing scripts for data tables ...... 7 Capturing scripts for analyses ...... 8 A general method for creating scripts...... 9 Use JMP interactively to learn scripting...... 10 Samples of JSL Scripts ...... 11 Data table programming ...... 11 Customized analyses ...... 13 Custom displays ...... 18 Matrix algebra with JSL...... 19 Scripting graphs ...... 23 Scripting instructional simulations ...... 25 1 Introducing JSL 3 Window > Window Hello, World Hello, Introducing JSL Introducing . (Windows and Linux) or and Linux) (Windows -R on Macintosh. won’t be enabled until something is written won’t a ViewLog > File>New>NewScript . e menus. On Windows and Linux, select Linux, and Windows On menus. e . New Script Run Script . On the Macintosh, select menu, select menu, select Edit Starting a New Script (Macintosh). Note that the Macintosh command that the Macintosh Note (Macintosh). New scripts can also be created from th from can also be created scripts New to the log. A="Hello, World"; A="Hello, Show(A); File > New > Script Shortcut: press Control-R on Windows and Linux or on Windows Control-R press Shortcut: Log 4these lines: type script editor, the resulting In Figure 1.1 3 click window, Starter JMP the In 5From the the 5From 1Start JMP. it. recognize you’ll Perhaps to a classic. hearkens back simple and is exercise This 1Start 2 open, open it by selecting isn’t the If log window Hello, World Chapter 1 4 Introducing JSL Chapter 1 Hello, World
Figure 1.2 Running a Script
The result is shown in the Log window. Besides showing results and errors, this window is also a script editor. Figure 1.3 The JMP Log
This is how you enter and submit JSL. You have just created a global variable, A, assigned a value to it, and shown its value. Notice that the log echoes your script first, and then echoes any results—in this case, the output for the Show(A) command. Go To Line As your scripts grow in size, it is handy to jump to specific lines in the script. Use the Go To Line com- mand from the Edit menu to jump to a specific line. This command is also useful during the debugging process, since error messages frequently mention the line of the script where the error occurred. 1 Introducing JSL 5 .” . While a . While fitmodel Hello, World Hello, ” than “ ” than Introducing JSL Introducing Stop Script -Period on Macintosh) to on Macintosh) -Period a Fit Model Fit Fit Model(and some Model(and Fit -loop to greet the world not just once the world not -loop to greet menu changes to menu changes For Edit , and make a few other changes to see how the how to see changes and make a few other , st of those commands have spaces in them. For For in them. spaces commands have st of those Show rry about reaching for the Shift key all the time. all the key rryShift for the about reaching -loop. This isn’t necessary for JMP’s sake; it just makes it a little it just makes sake; necessary JMP’s for isn’t This -loop. command in the the command in . Most people would rather see “ . Most For is item (or type Esc on Windows or on Windows Esc item (or type is are separated by parentheses, commas, semicolons, and various various and semicolons, commas, parentheses, by separated are script like this if you this want: you like if script quickly than you can stop them. them. can stop you than quickly -R on Macintosh) this time instead of instead this time Run Script a with the variable name. It just prints the the variablelabel with the name.results It that it except doesn’t Print lines inside the lines inside Show ,X=i;A="Hello, World";P r i N T( r World";P ,X=i;A="Hello, X,A));print("done"); is similar to 1 World" "Hello, 2 World" "Hello, 3 World" "Hello, 4 World" "Hello, "done" X=i; World"; A="Hello, print(X,A)); -loop works. -loop works. all text, select the text first and then press Con- press select the text first and then all text, of instead a window in text of the part submit (To or on Windows trol-R fo R(i= 1,i<5,i++ print("done"); for(i=1, i<5, i++, i<5, for(i=1, value. script the Stopping run a script, the When you 1this: to script the change script window, the In arguments inside parentheses) inside arguments operators such as +, –, and soon. Asfar as JMPconcerned, is spaces, tabs, returns, and blank lines come from most JSL words because is This exist. don’t JSL words or within operators inside or between graphical usual user interface (GUI), and mo JMP’s JSLwould the be Model, Fit instance,thatto do see later on you will Words in JMP’s scripting language scripting in JMP’s Words 2 the script as before. Submit Now try making this script do alittle more workby adding a For stop it. Many scripts execute more scripts execute Many stop it. Punctuation and spaces and Punctuation the indented Notice script is executing, you can select th can select you executing, is script Print but four times. Also, Also, four times. but easier to read. You could write this You easier to read. JSL isn’t case-sensitive, so you don’t havewo to case-sensitive, so you don’t JSLisn’t Modify the script the Modify Chapter 1 6 Introducing JSL Chapter 1 Hello, World
You do have to be a little careful inside a text string. In “Hello, World” extra spaces would affect the output, because text strings inside double quotation marks are taken literally, exactly as you type them. Also, you would get errors if you put spaces between the two plus signs in i++, (i+ +), or in numbers, (43 is not the same as 43). Generally, JSL uses: commas , between arguments inside the parentheses for a command. parentheses ( ) to surround all the arguments of a command. Many JSL words have parentheses after them even if they don’t take arguments; for example pi() has the parentheses even though π is just the number 3.14... Pi doesn’t expect an argument and will complain about any argu- ment you do give it. Therefore, Pi(mincemeat) would be considered an error (although it seems heretical to say so). But the parentheses are still required. semicolons ; to separate commands but also to glue them together. In other words, you use a semicolon to separate one complete message from the next, e.g. a=1;b=2, but what the semico- lon really does is tell JMP to continue and do more things. For example, the For-loop example showed how to put several statements in the place of one statement for the fourth argument, because the semicolon effectively turned all three statements into one argument. Trailing semicolons (extras at the end of a script or at the end of a list of arguments) are harmless, so you can also think of semicolons as terminating characters. In fact, terminating each complete JSL statement with a semicolon is a good habit to adopt. quotation marks " " to enclose text strings. Anything inside quotation marks is taken literally, exactly as is, including spaces and upper- or lower-case. Nothing that could be evaluated is evalu- ated; if you have pi()^2 inside quotation marks, it is just a sequence of six characters, not a value close to ten. See “Quoted Strings,” p. 34, for ways to include special characters and quota- tion marks in strings. For a more formal discussion of punctuation rules, see “Lexical rules of the language,” p. 32.
Save your script If you would like to save your script, just do this: 1 Make the script window active (click the “Untitled” window to make it the front-most window). 2From the File menu, select Save or Save As. 3 Specify a filename, including the extension .jsl (e.g., hello.jsl). 4 Click Save. Scripts are saved as text files, and you can edit them with any text editor. However, if you do edit scripts with applications other than JMP, be careful to save them as plain text files. If you preserve the .jsl extension, you can double-click a script file to launch JMP. To reuse a script, use Open from JMP’s File menu, double-click a .jsl file, or drag and drop the file onto JMP’s application icon. When opening a JSL file, the actual script is always opened in its own script window. However, it may be distracting to some users to see this window. To keep a script from opening in a script window, put //! 1 Introducing JSL 7 Introducing JSL Introducing ). command to bypass command to bypass Open hello.txt Saving and sharing your work your sharing and Saving ty who can’t simply look over your shoulder to simply look over ty who can’t y, and you’re tired of clicking the same buttons clicking the of tired and you’re y, sooner or later: JMP can create scripts to dupli- create can sooner or later: JMP detail, from beginning to end, such as to create to create as such to end, beginning from detail, pts, and in the future just run those scripts. Next Next just runscripts. pts, and in the future those ld be followed routinely by your lab technicians. your lab by routinely befollowed ld s—add rows and columns, change values, rearrange rearrange values, change columns, and rows s—add ewed with any text editor. Double-clicking a log file Double-clicking ewededitor. text with any on Windows (e.g., on Windows .txt window to make it the front-most window). front-most it the to make window lumn, make a row state column, and so on. on. and so state column, lumn, make a row . to select (highlight) the script. select (highlight) the to Save As. or Run Script Save menu, select menu, select menu, select Edit File Save the output shown in the Log window: in the output shown a look at and take runthe script Then, columns, sort the rows, make a formula co sortrows, columns, the an audit trail for a agencyorgoverning for peers reviewing your journal article. current data table()< Figure 1.4 The Get Script Command and the Log Now try running the script in the log window: 1 In the Log window, click and drag to select (highlight) the script, starting with New Table. 2From the Edit menu, select Run Script. The script produces a perfect clone of your data table. Capturing scripts for analyses Launch a platform—any platform, such as Fit Model. Take a look at the default results and then go exploring. Try options in the pop-up menus to see related tests and graphs. Work with the red pop-up menus in the report surface to get exactly the report you want. When you’re done, get a script to recreate your results. There are two methods of getting a script for your results. One is to use the Script submenu located at the bottom of each platform’s popup menu. This method is detailed in “Use JMP interactively to learn scripting,” p. 10. 1 First you need to figure out what JMP calls your analysis. This can be tricky in some cases, discussed in the “Scripting Platforms” chapter, but usually you can read it right off the title of the analysis window, after the name of the data table. For example, a window titled “Big Class: Fit Least Squares” would be called Fit Least Squares. 2 Now you have to specify “which one.” You might have fit several models before getting the one you want to keep. You need to tell JMP which one you want by supplying a subscript, which is just a number inside brackets after the name. If the third model you fit is the one you want, you would specify it as Fit Least Squares[3]. 3 You’re ready to get the script from the object: 1 Introducing JSL 9 Introducing JSL Introducing Saving and sharing your work your sharing and Saving for your final results? Get scripts to recreate recreate finalscripts to your for results? Get rms” chapter; here you’ll just try some examples. to put semicolons to put ( ; between statements. You ) in Did you exclude some rows? Did you fix errors? If so, If fix errors? you Did some rows? exclude you Did , depending on which steps you performed:you steps , depending on which . is? Write statement for it: an Open is? Write Run Script menu, select menu, select Edit Personality(Standard Least Squares), Run Model(Profiler(Confidence Run Model(Profiler(Confidence Squares), Least Personality(Standard Profiler(Surface Contour Functions(1)), Desirability Intervals(1), Plot(1)))) Fit Model(Y( :weight), Effects( :sex, :height, :sex * :height), * :height), :sex :height, :sex, Effects( :weight), Model(Y( Fit Set Property(Notes, "...usually used as a label variable in plots"), plots"), in variable as a label used "...usually Property(Notes, Set "JAMES", "TIM", "LILLIE", "JACLYN", "JANE", "LOUISE", Values({"KATIE", "MICHAEL", "JOE", "JOHN", "SUSAN", "ALICE", "BARBARA", "ROBERT", "FREDRICK", "PATTY", "CAROL", "LESLIE", "ELIZABETH", "JUDY", "DAVID", "AMY", "MARY", "JEFFERY", "CHRIS", "EDWARD", "LEWIS", "HENRY", "ALFRED", "MARIAN", "MARTHA", "DANNY", "MARK", "CLAY", "WILLIAM", "ROBERT", Numeric, New Column("age", "LAWRENCE"})), "KIRK", "LINDA", "PHILLIP", Values([12, adventurously"), data "Explore Set Property(Notes, Ordinal, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, Property(Notes, Set Nominal, Character, Column("sex", New 17])), 17, 17, "M", "M", "F", "F", "F", "F", Values({"F", adventurously"), data "Explore "F", "M", "F", "F", "F", "F", "M", "M", "M", "M", "F", "F", "F", "M", "M", "F", "M", "M", "M", "M", "F", "M", "F", "M", "M", "M", "M", "M", Set Continuous, Numeric, New Column("height", "M"})), "M", "F", "M", "F", 66, 55, 61, Values([59, data adventurously"), "Explore Property(Notes, 64, 62, 63, 63, 65, 61, 62, 59, 63, 58, 65, 61, 56, 60, 61, 51, 60, 52, 62, 68, 68, 60, 66, 65, 62, 65, 66, 67, 62, 64, 69, 68, 64, 64, 65, might have something like this: such as to color and labelplots? andin yoursuch as to color points data table. your you should get a script to recreate them. You’ll learn the details in the “Scriptingdetails learn Platfo in the the them. You’ll Bivariate[1]< 70])), New Column("weight", Numeric, Continuous, Set Property(Notes, "Explore data adventurously"), Values([95, 123, 74, 145, 64, 84, 128, 79, 112, 107, 67, 98, 105, 95, 79, 81, 91, 142, 84, 85, 93, 99, 119, 92, 112, 99, 113, 92, 112, 128, 111, 105, 104, 106, 112, 115, 128, 116, 134, 172]))); Bivariate(Y(weight), X(height), Fit Line({Confid Curves Fit(1)}), Where( :sex == "F")); Bivariate(Y(weight), X(height), Fit Line({Confid Curves Fit(1)}), Where( :sex == "M")); Fit Model(Y( :weight), Effects( :sex, :height, :sex * :height), Personality(Standard Least Squares), Run Model(Profiler(Confidence Intervals(1), Desirability Functions(1)), :weight << {Plot Actual by Predicted(1), Plot Residual by Predicted(1), Plot Effect Leverage(1)})); Scatterplot 3D(Y(age, weight, height)); 5Save the script. 6 If you share your JSL file with your colleagues, don’t forget to include any data tables or additional files along with the script. Use JMP interactively to learn scripting One of the simplest ways to accomplish anything is to get somebody else to do it for you, and writing JSL is no exception. The best JSL-writer you’ll ever find is JMP itself. This example shows how to work in JMP interactively and then save the results as a script to reuse later on. With simple modifications, this script can serve as a template for speeding up routine tasks. What JMP can and cannot do to help you write scripts JMP can automatically save scripts to reproduce any data table or analysis in its current state. You can pause any time in your analysis to save a script to a script window, in a data table, or in an analysis report. You can then modify the automatically-generated script as needed for future projects. JMP cannot record scripts while you are working. While script-recording is a useful feature in some other scripting languages, it is less important for a program like JMP, where the important thing is the results. You cannot use script-recording to observe how a sequence of interactive steps are performed. However, remember that you can save a script when you’re finished, and that script will reproduce everything you have accomplished. JMP’s scripting language is not intended to be an alternative command-line interface for using the pro- gram. JSL is intended for recreating results and for extending JMP’s capabilities beyond JMP’s intended use in data discovery. There’s more than one way to do it Since JSL is a very flexible language, you can accomplish things many different ways. Typically the script that JMP saves for you specifies every detail of your analysis, even if most of the details happen automatically by default. Does that mean that the scripts you write have to be just as complete and detailed? Not at all. You usually just need to specify the details you would specify when using the graphical user interface (GUI). For example, if you open Big Class and want to launch Dis- tribution for height, weight, and sex, you would only need to do this in JSL: 1 Introducing JSL 11 instead. ® Introducing JSL Introducing , etc. If you need to do you , etc. If Samples of JSL Scripts using the SAS System SAS the using Transpose , , you would see , this: you Summary power is in data discovery. If you need to manage with JSL. If you thinkto be pos- ought something , powerhouse data management tool. JMP has an inten- powerhouse apter has examples of scripts and their output. of scripts and their output. has examples apter to write a script to do the work for you. writea script to do the work to Subset rows at a time and stores the products in a column of a stores and at a time m rows , manipulations, consider manipulations, ripting advanced data table operations.ripting advanced Sort a try, and what happens. see a try, Save Script to Script Window Script Save Script to result *= (data table("Big Class"):weight)[j+1]); table("Big (data *= result (data table("Products"):result)[i+1]=result); (data result=1; for(j=i*m,j You could make a similar script for sums instead of products by replacing "Products" with "Sums", *= with +=, and changing result=1 to result=0. Another way would be to make a formula column to define m-row groups, and then use JMP’s built-in Summary capability: dt< Compare two data tables Here is a script to open two data tables, compare them, and report all results to the log window. This script makes heavy use of the For operator to loop operations over all the rows (loops with i), nested with another For operator to loop operations over all the columns (loops with j). /* COMPARE THE CONTENTS OF TWO DATA TABLES */ // First identify the two data tables to be compared. // Since you don't specify arguments, Open() presents the // host-system dialog box for opening a file. caption("Please locate the first data table.",spoken(1)); dt1=open(); caption("Please locate the second data table."); dt2=open(); // Check for differing sizes. if(nrow(dt1)!=nrow(dt2), write("Differing number of rows. "), write("Same number of rows. ")); if(ncol(dt1)!=ncol(dt2),write("Differing number of columns. "), write("Same number of columns. ")); nr = min(nrow(dt1),nrow(dt2)); nc = min(ncol(dt1),ncol(dt2)); // Check for differing column names. for(j=1,j<=nc,j++, current data table(dt1);n1=char(ColumnName(j)); current data table(dt2);n2=char(ColumnName(j)); if(n1!=n2, write("\!rDiffering column names in column "||char(j)); show(n1,n2))); // check for differing values e=0; for(i=1,i<=nr,i++, for(j=1,j<=nc,j++, v1 = Column(dt1,j)[i]; v2 = Column(dt2,j)[i]; if(v1!=v2, write("\!rDiffering values at row "||char(i)|| " in column "||char(j));show(v1,v2);e++))); if(e==0, write("Matching cells have the same values."), 1 Introducing JSL 13 . 240 Introducing JSL Introducing meet your exact needs. meet your Samples of JSL Scripts eated as a string, which eated which makes it as a string, possible to es, first learn about analysis platforms in general in general platforms analysis about learn es, first P’s built-in analyses to P’s ent the results in a custom report window similar window custom report a in results ent the e. To improve the script still further, you could you still further, the script improve e. To ent. You might might also want to take metadata such as ent. You , and then turn to “Constructingp. trees,” display stead of one at a time through the menus. 173 is used to switch between two open windows. open windows. two between to switch used is on the row state values, because row states are returned as expres- returned states are because row state values, on the row variate to do exactly that: Char() slider box (-5,5, myVarRatio, (-5,5, box slider fit); << (curve[2]< Figure 1.5 Example: Interactive Bivariate Here’s a brief explanation of how this script works. First launch Bivariate with the height and weight variables and request an initial spline fitting with tension 1000: biv=Bivariate(Y(weight), X(height),Fit Orthogonal(10^myVarRatio)); Then make a slider box that goes from –5 to 5 and sets a value for the global variable myVarRatio. The slider box then has a script that sends two messages to the Bivariate platform, the first to remove the current fit, and the second to add a new fit with the chosen variance ratio. slider box (-5,5, myVarRatio, biv << (curve[2]< Figure 1.6 Readings Data Table 2 Create another table that has the parameters needed, in this case LSL, USL, and Target: specs = New Table("SpecLimits.jmp", Add Rows(5), New Column("ColName", Character, Nominal, width(30), Values({"pH", "Specific gravity", "Temperature, degrees C", "Sediment, ppb", "Alcohol"})), New Column("LSL", Numeric, Nominal, Values([5.1,1.018,2,85,4.2])), New Column("USL", Numeric, Nominal, Values([5.35,1.003,6,115,4.3])), New Column("Target", Numeric, Nominal, Values([5.25,1.002,4,102,4.25]))); Figure 1.7 Spec Limits Data Table 3 Build all the analyses without actually showing them. First create a vertical list box that starts out with just a simple text box inside it, called vl. vl=vListBox(textbox("Spec Limits Script")); 4Then use For Each Row to iterate on the SpecLimits table, using Substitute to plug values from the table into a generic Distribution launch-command expression. Having built the command for one row of the SpecLimits table, you can switch to the Readings table and run the command inside a vertical list box called vv, which you don’t actually see because no win- dow was created for it. However, you can look inside vv to check whether the current Cp result is greater than 1, and if so close its main outline node. 5Next Append the result (closed or not) to that vertical list box created at the beginning, called vl. 1 Introducing JSL 17 Introducing JSL Introducing Samples of JSL Scripts vl. ble and loop through the remaining rows. to show all the displays in all the displays to show New Window New Capability Analysis(LSL(_LSL), USL(_USL), Target(_Target)))), USL(_USL), Analysis(LSL(_LSL), Capability expr(_C), ColName, expr(_C), lsl, expr(_LSL), expr(_USL),usl, expr(_Target),target); expr(Distribution(Y(_C), Quantiles(0),Moments(0), Quantiles(0),Moments(0), expr(Distribution(Y(_C), show(command); vv tree display in results store analysis, do the // currentDataTable(data); vv=vListBox(command); tree display in by looking the CP test // Analysis"][tableBox(2)][NumberColBox(1)]< Figure 1.8 Spec Limits Collection Custom displays You can also use scripting to create new displays from results that JMP already knows how to make. For example, quality engineers frequently study six common capability analysis displays for a process vari- able: an X-chart, a moving range chart, a histogram, a box plot, quantiles, and basic descriptive statis- tics. JMP provides each of these displays, but by default they appear in two different platforms: the two classic QC displays are in Control Chart, and the others are performed by Distribution. To view these results together in one window, you simply need to build a New Window that contains one parent Outline Box node with two results, one from Control Chart and the other from Distribu- tion. To do this, place the usual commands for launching the platforms inside VListBox, which is sim- ply a vertical container, and then glue the two containers together side-by-side with HListBox, which is a horizontal container. The HListBox goes inside one OutlineBox, and that comprises the contents of the New Window. csp=NewWindow("Capability Sixpack", OutlineBox("Capability Sixpack", HListBox( VListBox(cc=Control Chart(chart Col(Height, Individual Measurement,Moving Range),K Sigma(3))), 1 Introducing JSL 19 Introducing JSL Introducing ix operations, such as . Samples of JSL Scripts . Scripting adds the ability to . Scripting adds New Window m further tests, and the ability to make the JMP User Guide JMP User also a broad range of matr broad a also eigenvalue decomposition, and so on. Thus you can you so on. Thus and decomposition, eigenvalue launching platforms the through usual menus. ality to JMP: the ability towith matrices. directly work JMP can d over againdragging.and without all the clicking d over results with which can you results interact and perfor VListBox(dist=Distribution(columns(Height)))))); Capability Sixpack live matrix multiplication and division, determinants, multiplication and division, matrix own. perform of your calculations custom now do all the usual elementwise numeric and operations JSL adds an important new function new important an adds JSL The process for working with JMP’s display tree containers is simple: containers is display tree JMP’s with for working process The 1by need you results each of the create First, 2JSL. to get the corresponding platform each Script from Save use Then, 3a in pieces together inside containers glue the JSL Finally, Figure 1.9 If you all you want to do is arrange results from several analyses into a single report, you can use JMP’s chapter of the “Reports” in discussed Layoutwindow, combine same arrangements over an same arrangements over Matrix algebra with JSL Chapter 1 20 Introducing JSL Chapter 1 Samples of JSL Scripts For example, JSL has a straightforward notation for entering matrices: L=[1 2 3, 4 5 6, 7 8 9, 10 11 12]; M=[0 1 2, 2 1 0, 0 1 1, 2 0 0]; N=[1 2 3 4, 4 3 2 1, 0 1 0 1]; O=[0 1 2, 2 1 0, 1 2 0]; Simple operations look like this: R = L+M; // matrix addition [ 1 3 5, 6 6 6, 7 9 10, 12 11 12] Q=L*M`; // matrix multiplication of L by M-transpose [ 8 4 5 2, 17 13 11 8, 26 22 17 14, 35 31 23 20] You can even solve a linear system, that is, find the vector x for the square, nonsingular matrix A and vector b you specify such that xA= –1b : A=[1 -4 2, 3 3 2, 0 4 -1]; b=[1, 2, 1]; x=solve(A,b); [-17,5,19] For numerical work needing matrix factors, JMP offers operations such Cholesky, eigenvalue, and sin- gular-value decomposition: E=[ 5 4 1 1, 4 5 1 1, 1 1 4 2, 1 1 2 4]; L=cholesky(E); [ 2.2360679774998 0 0 0, 1.7888543819998 1.3416407864999 0 0, 0.4472135955 0.1490711985 1.9436506316151 0, 0.4472135955 0.1490711985 0.91465912076 1.7149858514251] You can read the numeric columns of a data table into a matrix to perform custom calculations: my matrix = current data table()< 4 1 , Y = 5 X = 3 7 5 β ε β β ε You want to solve for 0 and in the equation Y = 0 ++1X , which can be rewritten as β ε β β β Y X += , where is the matrix composed of vectors 0 and 1 , and X is a vector of ones for the constant term and the vector of measurements for the linear term, X. The task is to solve for β . Y=[4,5,7]; X=[1,1,1] // the constant term 1 Introducing JSL 21 b Introducing JSL Introducing Samples of JSL Scripts Y β at a time, butnormally youwould X b Y command at the end: end: at the command mize estimates of mize , denoted nor- the solving , by Show ˆ Y en you submiten the script one line Y Y T X 1 – X T () Squares), Run Model); Run Squares), [3.833333333333332,5.333333333333332,6.833333333333332] [0.166666666666668,-0.33333333333333,0.166666666666668] b:[3.0833333333333,0.75] Yhat:[3.8333333333333,5.3333333333333,6.8333333333333] e:[0.1666666666667,-0.333333333333,0.1666666666667] [3.083333333333332,0.75] = bX || // concatenated with with concatenated // || term linear the // [1,3,5]; myFit << save columns(residuals); columns(residuals); save << myFit dt = new table("myData.jmp"); = new dt column("Y",values([4,5,7])); << new dt column("X",values([1,3,5])); << new dt Least Personality(Standard :X), Effects( :Y), Fit Model(Y( = myFit Yhat=X*b; Yhat=X*b; e=Y-Yhat; yhat, e); show(b, b=inverse(x`*x)*(x`*y); b=inverse(x`*x)*(x`*y); probablyrun script at once and use a wholethe JMP’s Fit Model platform getsresults: the same Model Fit JMP’s The model’s residuals are the differences between the between the differences are residuals model’s The and the values values: estimated wh step at each the results see You First rewrite this expression in JMP’s matrix notation: JMP’s in expression this rewrite First of find fitted values Now denoted , multiplying by , and : The heart of the least squares technique is to mini The heart of the least squares mal equation: Chapter 1 22 Introducing JSL Chapter 1 Samples of JSL Scripts Figure 1.10 Matrix Algebra and Regression dt = new table("myData.jmp"); dt << new column("Y",values([4,5,7])); dt << new column("X",values([1,3,5])); myFit = Fit Model(Y( :Y), Effects( :X), Personality(Standard Least Squares), Run Model); myFit << save columns(residuals); An Add Rows command is not necessary, since new rows are automatically created with the values in the New Column command. If you had inserted an Add Rows command before adding columns, the default column Column 1 would have persisted in the data table. A more elaborate regression example appears in “Statistical examples,” p. 370, in the “Matrices” chap- ter. 1 Introducing JSL 23 Introducing JSL Introducing Samples of JSL Scripts rlying problem is that One data. . aphic displays or create your own graphs from graphs from own your or create displays aphic sigma=1.5 rve to draw one summation curve. Finally, the script rve to draw one curve.summation Finally, smooth shape for a set of data points, which can help which set of data points, for a smooth shape ows how kernel density estimates are formed by add- formed by are estimates density kernel how ows value interactively. interactively. value sigma best convey of best convey the shape the unde control for setting the for setting control Normal Density((x-data[i,1])/sigma)/sigma), x); Density((x-data[i,1])/sigma)/sigma), Normal xx = data[i,1]; = data[i,1]; xx x); Density((x-xx)/sigma)/sigma, YFunction(Normal // add a black "slider" handle for interactively controlling the controlling for interactively handle "slider" black add a // kernels underlying of the width // PenColor("black"); 2.25, sigma=x); Handle(sigma, change") to handle drag text({sigma,2.3},"sigma=",sigma,"; ); of kernels sum showing curve a red draw // Color("red"); Pen n, YFunction(summation(i=1, XScale(min(data)-3*sigma, max(data)+3*sigma), yScale(0,2.5), max(data)+3*sigma), XScale(min(data)-3*sigma, n = nrow(data); point data at each gray kernels draw // color("gray"); pen for(i=1,i<=n,i++, Handle ) GraphBox(FrameSize(400,300), double buffer, buffer, double GraphBox(FrameSize(400,300), ); // Kernel Density Estimate Demonstration Estimate Density Kernel // Business Basic Waterman. and Stine, Foster, by Inspired // 23-24. p. Springer-Verlag. York: New 1997. Statistics. // = [5,7,8,9.5,10,10.5,11,11.2,12,13,15,17,18]; data 1.5; = sigma Addition", t=NewWindow("Kernel the jagginess caused by a histogram’s squared-off bins squared-off can be distracting. the jagginess caused by a histogram’s density curve by given each data deviation a normal at point with draws some standard example This it adds together the heights of sigma.each cu Next adds a adds Here is the resulting graph using the initial setting, graph using is the resulting Here scratch. For example, here is a JMP script that sh is a JMP script example,here scratch. For together. ing kernel functions a estimate is to show idea of a kernel density The histo- at look is to A common method distribution. a normal come from points the whether assess it can be interactively, sizes bin histograms’ tool for adjusting hand JMP’s with even However, grams. determinedifficult which choices to Through scripting, you can extend JMP’s built-in gr scripting, you can extend JMP’s Through Scripting graphs Chapter 1 24 Introducing JSL Chapter 1 Samples of JSL Scripts Figure 1.11 Kernel Addition: sigma=15. The Handle is the small black marker at the top of the graph; click and drag this to change the sigma value. Here are a few snapshots after dragging to other sigma values: Figure 1.12 Kernel Addition: Handle Dragged to the Left 1 Introducing JSL 25 to suitthe distribution and the distribution Handle Introducing JSL Introducing -test compares the means compares -test t make interactive graphics— make interactive Samples of JSL Scripts distribution’s density function. distribution’s t approximates a normal distribution. . 277 is also a handle that you can click and drag freedom approximates a normal distribution. approximates freedom without much explanation, and many authors’ authors’ many and without much explanation, r words, how many subjects do you need in your in your need do you subjects many how r words, n an’s illustration use these data, try which you might an’s -statistics—tests on the t that rely rs in the test. For example, a test. For in the rs , showed JSL’s capability to capability JSL’s , showed ng and dragging. This capability presents exciting ng and dragging. This capability exciting presents 23 see “Scripting Graphs,” p. Graphs,” see “Scripting – 2 degrees of freedom. of freedom. – 2 degrees and see how it affects the shape of the affects it how and see with of sufficiently manyfreedom degrees df -test has n has -test t ional simulations r educators. ), minus the number of paramete number minus the ), n Kernel Addition: Handle Dragged to to the Right Handle Dragged Addition: Kernel distribution distribution with sufficiently many degrees of degrees many sufficiently distribution with t t distribution with just one degree of freedom. There There of freedom. degree with just one distribution t df=1; data = [0,3,5,6,7,9]; // Foster, Stine, Waterman's data Waterman's Stine, Foster, // = [0,3,5,6,7,9]; data You can try data of your own as well, but make sure to adjust the coordinates for canto adjust trybut the coordinates as well, make sure data of your own You p. “Scripting graphs,” example, previous The For more more about graph scripting,For Figure 1.13 substituting into the script above: script above: substituting into the range of your data points. Foster, Stine, and Waterm Stine, range of your data points. Foster, scientific graphics that respond to a user’s clicki user’s a to graphics that respond scientific opportunities fo t methods use statistical many basic example, For fact that a The degrees of freedom for a test is defined as the number of subjects in the sample (the sample size, size, sample (the the sample in number the of subjects as is defined for a test of freedom degrees The often denoted a so groups, of two Again, the othe sufficient? In are of freedom many degrees How results? randomsample to get reliable favorite values for the authors’ state textbooks Many favorite number seems to you need a samplebe 30. Do size of 30 before you can use statistics based on the normal distribution? function the density draws then blue, in distribution normal a for function the density plots script This for a for value to change the Scripting instruct Chapter 1 26 Introducing JSL Chapter 1 Samples of JSL Scripts New Window("t-distribution", GraphBox(Framesize(300,150), Xscale(-5,5), Yscale(0,.5), Double Buffer, pen color("blue"); YFunction(Normal Density(x), x); pen color("red"); YFunction(t density(x, df),x); text({0, df/80+0.01}, "df = ",df); Handle(0, df/80, df=floor(80*y)+1))); Figure 1.14 t-Distribution: df=1 Certainly there appears to be big differences between these two curves, especially at the tails. Now click the red marker next to the “df = 1” label, and drag that handle up and down in the graph. Watch how the shape of the distribution changes as df changes. Here are some snapshots. At df = 5, the similarity is pretty encouraging. Figure 1.15 t-Distribution: df=5 At df = 14, it’s hard to tell the difference. 1 Introducing JSL 27 Introducing JSL Introducing Samples of JSL Scripts t-Distribution: df=30 t-Distribution: df=14 = 30, the plots are almost identical. almost identical. are the plots 30, = df At Figure 1.17 Figure 1.16 Chapter 1 Chapter 2 JSL Building Blocks Learn the Basic Components of JSL JMP is scripted by a very simple language called JMP Scripting Language, or JSL. You may not need to ever learn JSL, because almost every feature in the product is accessible through a direct user interface, as well as through the scripting language. Even if you use JSL, you can usually get JMP to write the scripts for you rather than typing them in yourself. JSL will be most useful to the power user that wants to extend JMP past its normal operating realm, or for the production user who wants to automate a regularly scheduled analysis. JSL is used in many places in JMP internally. • Column Formulas are implemented internally in JSL. • Platforms are launched using JSL internally. • Platforms are interactively modified using JSL internally. • Some graphics are performed through JSL. This chapter shows how to recognize valid JSL in terms of how the language is written in text. It covers syntax. The next chapter, “JSL Operators,” p. 59, details many of the basic functions of JSL. The chap- ter “Programming Functions,” p. 91, discusses how to write meaningful scripts that do something use- ful. It covers semantics. First you have to learn how to write words and position commas and operators. Then you learn what the words mean and how to use them. Confusion alert! As you will learn in the section on logical operators, a single pipe sym- bol (|) represents a logical OR. In the interests of brevity, programming and scripting manuals commonly use a | to represent the word or when discussing alternative values. For example, a filepath can be either absolute or relative. So when we show an argu- ment to a filepath function as absolute|relative, this means that you enter either absolute to indicate an absolute filepath, or relative to indicate a relative filepath. More than two options can be strung together with an or pipe in this way. So, when you see words separated with a |, read it as or. Contents First JSL Script...... 31 The JSL Language ...... 31 Lexical rules of the language ...... 32 Data elements ...... 37 Operators ...... 38 Context: meaning is local ...... 40 Programming vs. scripting...... 40 Data table context ...... 41 Scoping operators ...... 42 Graph context ...... 42 Name resolution...... 42 Name-binding rules...... 43 Frequently-asked questions ...... 45 Function resolution rules...... 46 Using the Script Editor and Debugger ...... 46 The Script Editor ...... 47 The JSL Debugger...... 52 Help with JSL ...... 54 JSL Browsers ...... 54 Show Commands ...... 55 Show Properties...... 56 2 JSL Building Blocks 31 from the from , and given A and X First JSL Script Run Script ts enclosed in parenthe- enclosed ts JSL Building Blocks button. In the resulting text window, enter button. textthe resulting In window, e message is sent to. The same namemight mean The sent to. is e message s, such as matching parentheses, is a valid JSL a valid is parentheses, matching as such s, -R on Macintosh). The result should appear in a Log names, with message conten message with names, a New Script tirely different in another context. in another different tirely agging the mouse cursor over it. Select it. Select agging the over mouse cursor rentheses, which must be balanced.rentheses, data, and send commands to objects. to objects. commands and send data, X:20 World" A:"Hello, Title ( "A Box" ), "A Box" ( Title World", "Hello, ), ( "-----" box Text ) "OK" ( Button menu (or press Control-R menu on Windows, or (or press ); Message Name ( argument 1, argument 2, ... ) ... 2, argument 1, argument Name ( Message Dialog( X=12+8; World"; A="Hello, Show(X,A); ses: text window. text window. •separated commas. by are Items • characters interchangeably. UPPER-CASE and lower-case can use You • other messages. nested inside commonly are Messages Notice the following: Notice • blanks. embedded can have Names • pa enclosed in contents are Message JSL consists entirely of a nested fabric of of a nested message JSL consists entirely hold data, manipulateexpressions JSL This is how you enter and submit JSL. You have just created two global variables, variables, two global just created have You enter and submit JSL. you how is This th dependent on who is of JSL phrases meaning The and something en one thing in one context Now select the text in that window by dr by window that in the text select Now Edit Go to the JMP Starter window, and click the and click window, to the JMP Starter Go Almost anything that obeys punctuation certain rule expression, though it mightexpression, not be understood by the object it is sent to. is JSL a valid expression: Here the text: values to them. The JSL Language The First JSL Script Chapter 2 32 JSL Building Blocks Chapter 2 The JSL Language Lexical rules of the language The language consists of the following kinds of tokens. Each are discussed briefly in subsections below. Table 2.1 Kinds of tokens in JSL Token Example Commas and , and () parentheses Names sqrt Distribution Net Income Numbers and 12.3 Dates 1.24E9 31Oct99:23:59:59 Quoted strings "ABC" Matrices [1 2, 3 4] Lists {oil,vinegar} Associative Arrays { { "gps", [78.7812 35.7873] }, {"high schools", {"Cary", "Green Hope", "Panther Creek"} }, {"population", 127640}, {"state", "NC"}, {"weather", {"sunny", "warm"} } } Operators + - * / etc. File Paths "$SAMPLE_DATA/Big Class.jmp" Comments // the rest of a line after // is a comment /* these symbols start and stop comments of any length */ Commas Commas ( , ) separate items, such as items in lists, rows in matrices, or named arguments to a function. mylist={1,2,3}; yourlist=List(4, 5, 6); mymatrix=[3 2 1,0 -1 -2]; Note: when you have a sequence of commands to execute, you do not separate them with commas. Rather, you glue them together with semicolons, as discussed under “Glue,” p. 93. Parentheses Parentheses ( ) are used to group operations in an expression and to delimit arguments to a function, such as in root(49). Parentheses also delimit the end of a function name even when arguments are not needed. Consider e( ) below, where the empty argument “()” after “e” is what distinguishes JSL’s function for e from the name “e.” for(i=0,i<10,i++,show(i,e()^i)); Be careful that parentheses match—every ( needs an ), or else errors result. On Windows, the script editor can match fences (parentheses, brackets, and braces). Press Control-] with your cursor in any part of a script. The editor searches for fences, highlighting the text between the first set of opening and closing fences it finds. Repeat this process to highlight the next-higher fence. 2 JSL Building Blocks 33 ). ^ are are . For . For or ++ or – for age for Name( ) or + and and t if it doesn’t obey the t if it doesn’t are exactly the same exactly are The JSL Language The JSL JSL Building Blocks Forage , you have to put it inside quota- inside put it to have you , Name("foo") and (like tabs, and newlines)blanks, ignored, are sign is usually interpreted as a prefix operator, operator, sign as a prefix is usually interpreted foo in scientific notation with an E preceding the preceding E with an notation scientific in nguage as they are on the menus and dia- menus on the nguage as they are underscore, and canunderscore, continue with those as well as -)(*$%(*&$%A means 3 times 10 to the power 2, or 300. If you2, or 300. If times 10 to the power 3 means d page delimiters, double-byte characters, apostro- characters, double-byte page delimiters, d immediately with an E followed by a power of ten ten of power a by followed E an with immediately e midnight, January 1, 1904. However, you can you enter 1, 1904.January However, e midnight, , specifically commas and parentheses. parentheses. specifically commasand , , “a” is a name. Commands and functions have names, “a” , ed inside a special parser directive called special parser directive a ed inside a=3 ng or a special symbol operator (such as ion, that minus sign is part of the number. of the number. part is ion, that minus sign , the word “Log” is the name of JMP’s logarithm function. A logarithm name is any is the name JMP’s of “Log” , the word every time you use it in JSL: it in use everyyou time values in a variety of common are date/time Date/time values formats. notation Log(4) Name( ) date/time is harmless when it isn’t needed; for example, isn’t harmless when it is Why does the language allow blanks inside names? Because it is good to have names of to have names is good blanksdoes the language it inside names?Why allow Because la the the same in be options and commands logs, and because people think in terms names. The of multi-word price of allowing delimiters more JSL needs that is blanks 46 thing. and upper and lower case is not distinguished. For example the names For not distinguished. case is lower upper and and numeric digits, spaces,tabs, verticaltabs, line an phes, percent signs, periods, and backslashes: periods, signs, percent phes, Name 1E-20 0.314159265E+1 3E3 12 1.234 1 . Name("-)(*$%(*&$%A")=42; Name("-)(*$%(*&$%A")=42; print(foo+Name("-)(*$%(*&$%A")); foo=4; a-z A-Z 0-9 _ ‘ % . \ ‘ % . 0-9 _ A-Z a-z instance, to have a globalinstance,name variable to with the tion marks and tion marks equivalent. it needs to be quoted and rules above, plac Numbers numbers, decimal can be written as integers, Numbers missing numeric is the itself period by A single values. date/time or times, as dates, and of ten, power number”). a NANvalue (sometimes called for “not all numbers: example, these are For too. In the statement In too. not part of the number. You can follow a number can follow You not part of the number. 3E2 example For the number by. want to scale you E notat in ten of exponent negative a need Dates times and JMP supports If you precede a number with a minus sign, the minus sign, the minus minus a a number with precede you If and computed as a number of seconds sinc stored , as in: , as usingformat ddMonyyyy:hh:mm:ss.ddd the a date/timeliterally, value •the white-space characters comparing names, When Names A name is exactly what you think: something to call statement the in variable a global the numeric when assign instance, you 3 to For value a thing. Names haveNames a few rules: • must start with an alphabetic or character Names language token that isn’t a number a or a stri languagetoken that isn’t • you can still have a nameother is any that sequence of characters, bu Actually, Chapter 2 34 JSL Building Blocks Chapter 2 The JSL Language x = 14Feb2002:19:15:00; Several shorter forms can also be used for date/time literals: x = 14Feb2002:19:15; x = 14Feb2002; y = 19:15:00; y = 19:15; JMP has numerous operators for converting date/time values to strings in common notations, e.g.: invitation = "Would you like to dine with me on " || long date(x) ||"?"; "Would you like to dine with me on Thursday, February 14, 2002?“ These and other date/time subjects are detailed in “Date/Time Operators,” p. 79 in the “JSL Operators” chapter. Quoted Strings Strings are put in double quotes. Be careful to put in the end quote, or it will gobble up unintended text until it finds the next double quote. How do you put a double quote inside a quoted string? Inside quoted strings, you can use a special escape sequence \! (backslash-bang) to precede a code for special characters. For example, code "\!"" to mean the character string containing a double quote. Note: The null character is dangerous to use, because it is normally treated as the end of the string. Table 2.2 Escape Sequences for Quoted Strings \!b blank \!t tab \!r carriage return only \!n linefeed (newline) only \!N inserts line breaking characters appropriate for the host environmenta \!f formfeed (page break) \!0 null character (see warning)—type the number zero, not the letter O. \!\ backslash \!" double quote a. On Macintosh, this is CR (carriage return character, hex ‘0D’). On Linux, this is LF (line feed character, hex ‘0A’). On Windows, this is CR LF (carriage return followed by a linefeed, hex ‘0D0A’). Sometimes, long passages require a lot of escaped characters. In these cases, use the notation \[...]\ and everything between the brackets does not need or support escape sequences. Following is an exam- ple where \[...]\ is used inside a double-quoted string. jslPhrase = “The JSL to do this is :\[ a = “hello”; b = a||” world.”; show(b); ]\ and you use the Submit command to run it.”; 2 JSL Building Blocks . 35 } and { ), prefix (with one argu- ), prefix 107 in the The JSL Language The JSL JSL Building Blocks a=7 , or simply between in = Other languages Other call this type of , or edence (the order in which opera- in which (the order edence List( ) 3+4 e more flexible than matrices. Lists are a matrices.are Lists than flexible e more in + s, text strings, expressions, matrices, and even even and matrices, s, text strings, expressions, s, numbers, dates, matrices, lists, etc. For example: etc. For s, numbers, dates, matrices, lists, mmon arithmetic actions. Operators come in sev- 103 in the “Programming Functions” chapter Functions” 103 in the “Programming r expression. You can represent an empty matrix of empty an can represent You r expression. brackets, values with separated by blanks or other . erators, listed in order of prec order listed in erators, -namealso,equivalents,appears and a complete list “JSL in the ngth in the “Matrices” chapter. chapter. in the “Matrices” ngth for logical negation), or postfix (with one argument on its left side, left argument on its one (with postfix for logical negation), or . ). ). !a a [] Function() are compound data structures, but they ar but they data structures, compound are lists for incrementing for incrementing a++ { }, [ ], ++, ––, ++, }, [ ], { ^, !, –, cary=Associative Array(); cary=Associative = "NC"; cary["state"] 127640; = cary["population"] 35.7873]; [78.7812 = cary["gps"] "warm"}; = {"sunny", cary["weather"] Creek"}; "Panther Hope", "Green = {"Cary", schools"] cary["high A = List(1,2,B,sqrt(3), List(a,b,3)); = List(1,2,B,sqrt(3), A A = {1,2,B,sqrt(3),{a,b,3}}; A=[1 2, 3 4]; 2, A=[1 A from element column second row, the first picks subscript // two=A[1,2]; Empty=[]; such as such ment on its right side, such as as such its right side, ment on JSL’s operators all have JSL’s way to store numerous items of different type: number items of different numerous store way to other lists. Lists can be expressed as arguments forthe function p. Arrays,” “Associative length under at greater discussed are arrays Associative chapter Functions” “Programming Operators two-character one- andOperators are forco symbols infix (with arguments on either side, such eral varieties: as Lists Like matrices, p. length under “Lists,” at greater discussed Lists are Matrices are discussed at greater le at greater discussed are Matrices Matrices as signed be specified can numbers inside Matrices to repre- used also are Brackets semicolons. or commas separated by and rows characters, space white occur afterwhen bracketssent subscripting, anothe by and no columns no rows Arrays Associative An associative arrayke maps uniqueys to values (possiblynon-unique). A key is aor singlea quote“hash table”. string, a “hash map” a “map”, data structure a “dictionary” be string can that key with value associated the while curly braces: Operators” chapter. These are the op chapter. These are Operators” tions are performed): performed): tions are Chapter 2 36 JSL Building Blocks Chapter 2 The JSL Language *, :*, /, :/, +, –, ||, , |/, ::, <<, ==, !=, <, <=, >, >=, <= <, < <=, &, |, =, +=, –=, *=, /=, ; Note: Usually white space is ignored in JSL, so that “for age” and “forage” are the same thing. There is one exception: the two-character operators must not have a space between characters, or they will be misunderstood. Type these without spaces in between: ||, **, <=, >=, !=, ==, +=, -=, *=, /=, ++, --, :=, |/, <<, ::, :*, :/, :^, //, /*, */ File Paths In JMP, the preferred file path format is the POSIX (aka UNIX) format, with forward slashes as separa- tors. Each host still accepts its native format for compatibility. This, along with path variables, often eliminates the need for if(host is(...)...) logic to open files in a portable script. Path variables are supported at the beginning of a POSIX path. JMP recognizes HOME, DOCUMENTS, SAMPLE_DATA, SAMPLE_IMPORT_DATA, SAMPLE_SCRIPTS, and TEMP as path variables. They are used with a dollar sign at the beginning of a path. Open("$SAMPLE_DATA/Big Class.jmp") Users can also add their own path variables, or override some of the built-in ones with the JSL func- tions posixPath = Set Path Variable(varName, posixPath); posixPath = Get Path Variable(varName); varName is case-sensitive and does not include the dollar sign. Confusion Alert: You cannot override HOME, DOCUMENTS, or TEMP, and Get Path Vari- able does not retrieve the settings for them. Instead, use this JSL function: posixPath = Convert File Path(“$HOME”); There are JSL functions for accessing the default directory: posixPath = Set Default Directory(posixPath);// resulting current dir is returned posixPath = Get Default Directory(); The default directory is used for resolving relative paths. The file search list is also used for resolving rel- ative paths for opening files (not for saving). You can convert among file paths using the Convert File Path command. Convert File Path (path, • data table columns Operators In order to make writing algebraic expressions natural, JSL has adopted certain special character opera- tors, which are translated into the same meaning as if the phrase had been written as a message or func- tion. For example, the following two statements are equivalent: Net Income After Taxes = Net Income - Taxes; Assign(Net Income After Taxes , Subtract(Net Income, Taxes)) The assignment operation can be written either as a function Assign or as an infix operator =. Simi- larly, subtraction can be done with the Subtract function, or the infix minus sign; they are equivalent inside JMP. Another common operator is the semicolon ( ; ). The semicolon is a gluing operator that is used to both separate yet join one expression to another in a programming sequence. The function equivalent of this is Glue, so a;b is the same as Glue(a,b). The semicolon or Glue operator returns the result of its last argument. It is also legal to end an expression with a semicolon. This may lead you to think of it as a statement terminator like some other languages, but it is designed as an infix operator. Terminating semicolons are allowed at the end of a script stream and before a closing parenthesis or closing brace: ) or }. Following are operators and their Function( ) equivalents. The operators are grouped in their order of precedence, where the binding priority decreases with each group. For example, in a*b+c, the multi- plication a*b is done before the addition of c. For details, see “JSL Operators” chapter. Table 2.4 Operators and function( ) equivalents, in precedence order Operator Syntax Explanation {} List {a,b} Construct a list. List(a,b) [] Subscript a[b,c] Subscripts identify specific elements within a data ele- Subscript(a,b,c) ment a, where a could be a list, a matrix, a data column, a platform object, a display box, etc. ++ Post Increment a++ Adds one (1) to a, in place. Post Increment(a) –– Post Decrement a–– Subtracts one (1) from a, in place. Post Decrement(a) ^Power a^b Raise a to exponent power b. With only one argument, 2 Power(a,b) is assumed as the power, so Power(x) computes x2. Power(x) – Minus –a Reverses sign of a. Minus(a) ! Not !a Maps nonzero values to 0, maps 0 values to 1. Not(a) * Multiply a*b Multiplies a by b. Multiply(a,b) 2 JSL Building Blocks 39 . .) b. b 45 to and a b. means JSL global and and ::a a The JSL Language The JSL JSL Building Blocks . propagate missing values. missing values. propagate , and b b a by or a a tion for matrices a . . a object divides to . interprets the argument interprets as a denominator b from from b . See “Global scoping operator,” p. operator,” scoping “Global . See a and a message meanstable data column . Horizontally concatenate matrices. Horizontally concatenate matrices. Vertically matrices, generates the integers from For :a Send values. 1 if true, Return compare Booleans 0 if false. to in either values Missing Elementwise multiplica Elementwise Divide(x) matrices for division Elementwise Adds Subtracts together. strings Concatenates where for scoping, also used as infix operators (Colons are variable Divide(a, b) Divide(a, and implies 1 as the numerator, yielding the reciprocal 1/ reciprocal the yielding the numerator, as and implies 1 x Explanation ) b ) a, , b , a, equivalents, in precedence order (Continued) order precedence in equivalents, )... ) b , ) ) b message a, b ) b matrix2 ) )... matrix1 ) ) a, )... b matrix2 ) b a, b ) a, matrix1 b b |/ || ) ) b a, b a, << object a, a, a, b b b b b Send( a:* EMult( ab Greater( a>=b or Equal( Greater matrix1 VConcat( a:: Index( a==b Equal(a, a!= Not Equal( a/b Divide( Divide(x) a:/ EDiv( a+b Add( a–b Subtract( a|| Concat( matrix1 Concat( matrix2 message object matrix2 Syntax Operators and function( ) Less Equal Less or Greater or Equal Greater Equal Not Equal Add Subtract :* EMult > >= != < <= << Send == |/ VConcat :: Index – || Concat :/ EDiv + Operator / Divide Table 2.4 Chapter 2 40 JSL Building Blocks Chapter 2 Context: meaning is local Table 2.4 Operators and function( ) equivalents, in precedence order (Continued) Operator Syntax Explanation <=, Less Equal Less a<=b Context: meaning is local The JSL language is used both for scripting and programming. Programming emphasizes results, which build from the inside out. Scripting emphasizes context, which builds from the outside in. Understand- ing this distinction is crucial to understanding how JMP executes a script. Programming vs. scripting For example, consider how a typical programming statement evaluates: x = Log(a*b^(c + d)); The goal of this program is to find a result to assign to x. According to the rules of precedence for arith- metic operators, this starts on the inside by evaluating c and d and adding them together. Next b is eval- uated and then raised to that power (cd+ ), and that result in turn is multiplied by the evaluation of a. 2 JSL Building Blocks a 41 Big takes Fit Fit a*b means the interac- means a*b JSL Building Blocks is to be the response term. response to be the is c Context: meaning is local meaning Context: m, and finally that result is result that m, and finally actual row, say the third, you’ll you’ll the third, say actual row, table, which can be set or displayed set or displayed be can table, which models. This platforminturn knows columns assigned to the global variables variables the global assigned to columns and worked its way out. its way and worked table. If a script needs to refer to a specific cell to a specific table. If a script needs to refer model, and in that context, the phrase the phrase and in that context, model, instead use subscripts to ask for a row specifically. specifically. instead use subscriptsaskforrow to a c + d are columns such are the as indata sample table and iterate the division a row at a time down the down time a at a row the division and iterate ans that the following statement would its on following own ans that the row number. For formula columnexample, this gives For number. row atform and return a report. Evaluation starts the on Evaluation report.aatform and return . ratio weight above, it meant to multiply, but here but here it meant to multiply, above, ratio and and means that the column assigned to Y started on the outside with Evaluation to work. and goes script to set the current row to an row to set the current script function, which finds the logarith which finds the function, Height to the Weight in row 1: in row to the Weight Height height Log that determines the cells of the data cells of the that determines the , which calls JMP’s platformfitting for which calls JMP’s , Run Model , e.g. , which in turn are evaluated as the data the data as evaluated are turn , which in b Row() and is specifying the independent terms of a independent specifying the is Fit Model Fit a . Evaluation started on the inside with inside the startedon . Evaluation x and worked its way in. way its and worked : . The platform also knows that The platform also knows . Effects b row()=3; ratio = height/weight; ratio row()=3; = ::ratio height[3]/weight[4]; column("ratio"); new = height/weight); row(:ratio each for new column("Ratio B", formula(Height/Weight[1])); B", column("Ratio new number row current // returns Row(); current row third the // makes Row()=3; height/weight; = ratio new column("Ratio", formula(Height/Weight)); column("Ratio", new Fit Model(Effects(a, b, a*b), Y(c), Run Model); Run Y(c), b, a*b), Model(Effects(a, Fit and that Finally the platform sees Finally assigned to tion term of This version divides the height in row 3 by the weight in row 4: in row weight the 3 by row in the height divides version This a column create is to another possibility Still whole column: But if you include something in the you if But and row the current ignore is to Another possibility with the operator meis always 0, which row default, the current By areturn missing value and be generally useless: variableassignedto the global get a result This gives the ratio of each row’s row’s of each the ratio gives This number row a current is There outside with of the data A formula column is evaluated the rows down give a subscript to a specific you then each time, where the ratio within each row, That result is next passed to the to passed is next That result pl launch an analysis is to this script of goal The Model Now consider a typical scripting statement: a typical consider Now Class on a whole new meaning. In the program meaning. In new on a whole Data table context Chapter 2 42 JSL Building Blocks Chapter 2 Name resolution If you’re working with global variables, pre-evaluated statistics, and so forth, there’s no need to consider the current row. (Pre-evaluated statistics are single number values computed from the data table, as dis- cussed in “Pre-evaluated statistics,” p. 170 in the “Data Tables” chapter.) ::myCalc = col mean(height) / col mean(weight); Scoping operators The scripts in the previous section used colons : or double colons :: in front of some names. These are scoping operators that tell JMP how to interpret the names that follow in cases that could be ambigu- ous, such as when you have both a data table column and a JSL global variable with the same name. Scoping operators and the rules for name resolution are discussed in detail under “Name resolution,” p. 42, later in this chapter. :x; // data table column ::x; // JSL global variable x; // depends on state when first used Graph context If the script is inside a graph (such as the plot at the top of a Bivariate platform), then the graphics com- mands are processed by their containing Graph Box. You can store graphics commands, intermixed with expressions, inside any graphics frame. For example, if you wanted to superimpose four sine waves inside a graph, you could right-click (Windows) or Control-click (Macintosh) the graph, and then enter the following JSL into the dialog: For(i=1, i<=4, i+=.1, YFunction(Sin(x/i),x)); Or if you wanted to make a separate graph of the sine waves, you would enclose the command inside a Graph Box command, which constructs a new graph, and in turn enclose the graph in a New Window command: new window("Sinusoid", Graph Box(FrameSize(500,180),XScale(-10,10),yScale(-1,1), For(i=1,i<=4,i+=.1,YFunction(Sin(x/i),x)))); In either case, it is up to the graph box to determine what x is. Name resolution The following kinds of objects can be identified by name: • Columns and table variables in a data table • Global variables which exist for a session • Scriptable object types • Parameters and Locals inside formulas 2 JSL Building Blocks 43 As , ...); , ...); and Chart Name resolution , a and setting values in JSL Building Blocks ceptions are function definitions, definitions, function are ceptions As Column() Bivariate , session to hold values. Globals canto hold session contain and references to objects. They are called globals are to objects. They and references rather than to get or set a value, not resolved. are e column or table variable; is important when getting is closed, then it re-resolves the is closed, then it re-resolves next time it gets or the evaluatorthe using the rules If in this section. value, then it refers to a column in a data table, in a data table, to a column refers then it value, launch a platform specifying certain columns to be e referring to a column, when to a global, anda column,when to when to referring e Distribution used to get or set a value, and its resolution persists its resolution and value, a used to get or set (as an L-value), and create use a global variable. ’s name directly to refer to the object.to refer to directly name ’s are always resolved respectively as respectively always resolved are :: een opened the meantime.in Other ex , look it up as a data tabl it up look , , look it up as a global variable; a global variable; as it up look , and and : :: : . , fordetails; 46 no global, local, or parameter of that name already exists, exists, or parameter name already global, local, of that no p. Ratio = Height/Weight; = Ratio 1; = N + N (...) Distribution if 6the target of an assignment as used if then, A name in a script is resolved the first time it is the first time it is resolved name in a script A The operators thereafter. Global() From a programming point of view, name resolution name resolution point of a programming view, From Now the trick is to learn the rules as to when you ar Now en its meaning is usually the name of an option or of an name the usually meaning is then its object, for an is just part of a script a name If by in the object. Otherwisemethod is considered it context. specific not just in some anywhere, almost to referred be can because they the time, you can just use an object of Most to a type, so that you when know you can use the name directly and when you need to qualify it some- how. to for name-reference, referred that are Names script. name by parentheses,is followed then as a function. it is regarded Otherwise, the name is looked up as some object. of a remainder for the names that exist are variables Global lists, strings, including numbers, values, of types many justRatherpassed along, as with a scriptare to they analyzed. in order: following JMP tries each of the any name in a script. for resolutions six possible are There 1pair of parenthesesa by if followed ( rules,” resolution as a function;it uplooksee “Function ), 2by then if not prefixed 4localup as a then look it variable; 5platformup as a then look it launch name (e.g. 3by then if not prefixed Exceptions a nameIf is resolved to a column in a data table that sets in case the data table has b column formulas, and nonlinearformulas. column to a table refers name When unscoped an set a or get to is resolved name an unscoped When ratherthan a global • Name-binding rules Chapter 2 44 JSL Building Blocks Chapter 2 Name resolution • and the data table in context has a column of that name, • and – either the current row is set to a positive value, Warning: The current default row is now 0 instead of 1, as in JMP 3 and earlier. – or the name is subscripted, e.g. A[i]. If the data table has a table variable by that name, then the table variable takes precedence. In all other cases, it binds to a global, local, or parameter. Note: When an unqualified name in JSL is resolved to a data column in a data table, it must be associ- ated with the current data table. This is different than the rule in JMP 4 and earlier. The earlier rule was that if a name in a script was resolved to a data column, then it would stay with that data column even if the data column was not associated with the current data table. Exceptions Column formulas and nonlinear formulas. Column scoping operators Column scoping operators can be used to force names to be resolved as columns. 1 The prefix colon ( : ) means that the name refers to a table column or table variable only, never a global. The prefix : refers to the current data table context. The current data table is the data table that Current Data Table() either returns or is assigned. :colName 2 The infix colon ( : ) operator extends this notion to specify which data table has the column by using a data table reference (data table references are discussed in the chapter “Data Tables,” p. 113). The function equivalent is As Column. dataTableRef:name; As Column(dataTableRef, name) Therefore, these are equivalent: :name; CurrentDataTable():name; As Column(CurrentDataTable(), name); The Column function can also be used, but it always evaluates its arguments, and you need to specify a row to make it refer to a cell rather than the whole column. Column("X"); // refers to column X. Column("X",12); // refers to the cell of row 12, column X. Column("X")[]; // refers to the cell of the current row of column X Column(a); // evaluates a and looks up the column of the result. 2 JSL Building Blocks 45 As As Name resolution JSL Building Blocks used as used as an infix operator to optional data table reference reference data table optional to beevaluateddata to as a table beevaluated to vari- as a global lid row, in this case the third row. The row. in this case the third lid row, name name time to see how this works. These scripts assume scripts These works. this how to see time , rather than as a global variable. ad after the first resolution. Infix scope ad after operators Infix the first resolution. dt rred to by name, and a column reference? name, and to by a column reference? rred do I assign a value to a cell in the column? to a value I assign do Scoping operator. Forces Forces Scoping operator. the column in the by table given argument, Forces Scoping operator. able, not a data table column. also is that double-colon (Notice ranges.) represent Explanation to force names to be resolved as double-colon The as globals. prefix names to be resolved to force ) ) name , dt name s that define globals s that with the script same writing are if you e—especially assignment to set the current row to a va assignment row to set the current name name : name dt As Column( As Global( Row()=3 Scoping operators . ) means that the name refers to a global only, never a table column. The function equivalent is ) thatmeans to a the name global refers only, // assumes a data table with a column "A" and sufficient rows sufficient "A" and column a with table a data assumes // 1 A to row of the current //sets A=1; row()=3; 2 A to row of the current //sets :A=2; row()=3; 3 A to row of the current //sets :"A"=3; row()=3; A to column refer to ColA the global //sets ColA=Column("A"); to 4 of A row the third //sets ColA[3]=4; 6 to be for A the formula //sets ColA< Confusion alert! The current row for scripting is not related to rows being selected (highlighted) in the data table or to the current cursor position in the data table win- dow. The current row for scripting is defined to be zero (no row) by default. You can set a current row with Row, e.g. Row()=3, but please note that such a setting only lasts for the duration of that script, and then Row() reverts to its default value, zero—so submitting a script all at once can produce different results than submitting a script a few lines at a time. Another way to establish a current row for a script is to enclose it in For Each Row, which executes the script once for each row of the current data table. See “What is the current row?,” p. 127 in the “Data Tables” chapter, for more infor- mation. Will a scoping operator “stick” to its name? Yes. Once you use a scoping operator with a name, that name continues to be resolved accordingly for all subsequent occurrences of the name. For example, if you want to protect against clobbering data tables that happen to contain a column named “i” when you use i as an index inside a for-loop, simply declaring ::i at the head of the script is all the protection you need for the whole script. ::i=1; for(i=1, i<10, i++, doScript); Normally this wouldn’t be a problem since at time of execution Row() would typically be 0. However, if Row() is greater than 0, such as inside a For Each Row loop, you should be careful: ::i=1; for each row( for(i=1, i<10, i++, doScript)); Which has precedence when scoping, ":" or "[ ]"? Scoping occurs before subscripting. This means that these two lines of code are equivalent: dataTable:colName[i] (dataTable:colName)[i] Function resolution rules A name followed by a parenthesized list of arguments is the syntax for a number of contexts in JSL: • a call to a built-in function • a call to a user-defined function • a named argument, or • a nesting in a script for an object: either an option with an argument, or a sub-object with messages, or any other use recognized by the object itself. Using the Script Editor and Debugger JMP provides both an editor and a debugger for writing and troubleshooting your JSL scripts. 2 JSL Building Blocks 47 JSL Building Blocks -Space on Macintosh); on -Space Using the Script Editor and Debugger and Editor the Script Using and anywhere else you may edit or write a script. may else you anywhere and gure JSL environment and reading a friendly for writing 2.1) provides The Script Editor The Script Color-Coding colors for JSL: the following uses script window The • for comments; green • blue for JSL operators; • magenta dark for string values; • dark cyan and bold for scalar values; •JSL operators; over when hovering tooltips •global symbol; a over hovering when value-reporting • brace matching; live • highlighting matching braces; • expressions; using regular find/replace • automatic formatting. window in the log also used script editor is The The script editor has several useful features: several has script editor The •code; for JSL and SAS color-coding • or a Control-Space JSL operators (type for auto-completion The Script Editor (as shown in Fi (as shown Script Editor The scripts. Figure 2.1 The Script Editor Chapter 2 48 JSL Building Blocks Chapter 2 Using the Script Editor and Debugger • black for everything else. Colors may be customized in Preferences. See “Setting preferences for the script editor,” p. 50. Type-Ahead If you don’t remember the exact name of an operator, you can type part of the name and then type Control-Space or Control-Enter (a-Space or a-Enter on Macintosh) to see a list of operators that match what you have typed so far. For example, if you want to clear your JSL variables, but don’t remember the command, you can type clear, then Control-Space, to see a list of two possible clear commands (as seen in Figure 2.2). Figure 2.2 Type-Ahead Example Click the command you want to replace what you typed with the command. Tooltips If you are using an operator and don’t quite remember its syntax or what it does exactly, you can hover over it to get a brief explanation (see Figure 2.3). This only works with JSL operator names. They are colored blue in the script editor. Figure 2.3 Tooltip for a JSL Operator The tooltip shows the grammar, any arguments, and a brief explanation of the operator. You can also hover over variable names to see their current value (see Figure 2.4). Figure 2.4 Tooltip for a JSL Variable myVar holds 8 myVar holds Eight after running after running the the first line. third line. 2 JSL Building Blocks 49 field. . After running 8 JSL Building Blocks andmatch its are high- Replace with shows that its value is value its that shows Searching and replacing is the same as for is the same and replacing Searching Using the Script Editor and Debugger and Editor the Script Using to replace the current occurrence and find occurrence the current to replace myVar , and then type the closing brace, the script edi- ), you canthe script haveformat editor it for es in the Preferences window. See “Setting prefer- “Setting See window. Preferences the es in ening or closing brace, it brace, ening or closing Replace ing. Anyscript (for generated saving a example, by square brackets,square and curly braces in two ways: . th tabs in appropriate and returns th places. to the list of globals and assigned a value. a assigned and list of globals to the . . If you hover over a variable running before no tip script, the over you hover . If it, enter the replacement text in the text in replacement enter the it, shows highlighted matching braces in the third line of code. of line third in the matching braces highlighted shows d when you type an opening brace; opening type an d when you a match, it is highlighted in red; is highlighted a match, it 47 is poorly formatted (for example, older saved JMP scripts that may that JMP scripts saved older (for example, poorly formatted is for details. Search > Find > Search 50 Reformat Script oxes you wantto use. you oxes for details on the Search window. for on the details Search field, enter the text you want to search for. menu options are now available in scripts. available now menu options are menu, select menu, select menu, select menu, select to find the next occurrence, or click to find the next occurrence, Edit Edit Find what Find JMP User Guide JMP User Edit > Search y formed; for example, if your parentheses aren’t aren’t alertscommand parentheses This if your you if your script is badl y formed; for example, lighted in blue; if it does not have if it does blue; in lighted the next. 3 you If want to find text and replace appears.yetbeennot The variable added has the third line, the line, value changes the third to Eight Brace-Matching match parentheses, you editor helps script The • matching the brace is closing adde •an op to either cursor next place your when you ences for the script editor,” p. ences for the script editor,” Find/Replace The • you double-click a brace, everything If selected. the matching braces between is Figure 2.1 p. “The Script Editor,” between in code add type an opening brace, you When accidentally you from you,automaticallyfor preventing it added brace the type over to you tor allows closing brace. adding an additional can on and off the auto-completion turn of brac You platform script) is automatically formatted wi Automatic Formatting The script editor caneasierscript fora format read have all commands strung together with no whitespace See the See that a script write or open you If you. From the 1From the the data tables. 1From 2In the the 2In Tip: matched. After running the first line, hovering over any instance of any instance over line, hovering After runningfirst the 4 other checkb any Select 5 Click Chapter 2 50 JSL Building Blocks Chapter 2 Using the Script Editor and Debugger Setting preferences for the script editor You can customize several parts of the script editor. Open the Preference Settings window by selecting File > Preferences. Setting the fonts On the Fonts page, you can set the typeface and size for all script windows in JMP: Figure 2.5 Changing the Font for Script Windows Click Mono and set the font. For more details, see the JMP User Guide. Setting editor preferences On the Script Editor page, you can make many other customizations: Use tabs Check this option to enable tabs in your scripts. If it is unchecked, any tab you type is replaced by spaces. This is on by default. Tab width Enter how many spaces a tab should indent. If you have disabled tabs, any tab you type is replaced with this many spaces. The default value is 4. Extra space at bottom of document Check this option to enable scrolling the last line of a script to the top of the script editor. This is on by default. Auto-complete parentheses and braces Check this option to enable the script editor to auto- matically add closing parentheses, square brackets, and curly braces when you type an opening one. This is on by default. Show line numbers Check this option to show the line numbers on the right side of the script editor. This is off by default. Show operator tips Check this option to see tooltips for JSL operators. This is on by default. Show indentation guides Check this option to see faint vertical lines that mark indentation. This is on by default. 2 JSL Building Blocks 51 New Window , or get information from , or get information from JSL Building Blocks pt editor to add spaces between pt editor to pt editor to add spaces between spaces to add pt editor Using the Script Editor and Debugger and Editor the Script Using ts for automaticallyscripts. formatted This is : a script to write, changea script to Adds the string argument to the end of the script the end of the the string argument to Adds window. Places all the text in the script window in a single a single in script window the text in the all Places string. all the text in the currently script win- Removes argument. stringthe it with and replaces dow ww (see Figure(see your select and box color the click 2.6), e, turning on this option results in results option turning on this e, Check this option to cause the scri to cause the Check this option Check this option to cause the scri r variable values. This is on by is on by This see tooltips for variable values. Check this option to rtionwindow: of the script . This is on by default. by on is . This NewWindow Color selection Color Messages for a Script Box Object Box for a Script Messages parentheses, brackets, and braces and their conten and their and braces brackets, parentheses, default. on by instead of default. words within operator names. For exampl For names. operator within words ed << get text() get ed << text("string") set ed << text("string") append ed << ww = new window("scripttest", <