<<

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 . Hodgson Neil

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- 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 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)]<1,vv[OutlineBox(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, , , ); For the arguments above, the defaults are absolute, POSIX, and a base path of the default directory. The input path may be in Windows or POSIX style. 2 JSL Building Blocks 37 punctua- in syntax in syntax col in syntax sum- function (repre- function db /*...*/ form continues until /* The JSL Language The JSL JSL Building Blocks or Scriptable class subscripting subscripting or Scriptable class function (represented by (represented function Current Data Table() Data Current from being seen by users of the script. users of seen by being from or elements and expressions. JSL uses the following the following JSL uses elements and expressions. to values, which can be just aboutwhich to values, any other data that are ignored by the parser. Comments can be the parser. by ignored are that Column() Open() s, including nested lists and expressions lists and expressions nested including s, obtained from platform launches c=1+ /* */ comment 2; c=1+2; form continues until the end of a line. The Start a comment line; doesn’t have to be at beginning of line, but doesn’t a comment line; Start a comment. the line is of end to the everything following text Script script. of line a of middle the in appear can that A comment The is undisturbed. comment after the and before tion is a convenient way to remove portions of script temporarily. The portions of script temporarily. way to remove a convenient tion is equivalent:following are // obtained from the obtained from reports or parts of reports in windows (represented by by (represented windows in reports of parts or reports obtained from the obtained from . The in syntax summaries) syntax summaries) in /* or in syntax summaries) to the beginning of a script to prevent it prevent to to the beginning of a script // /* comment /* comment */ // comment . Comments cannot be inside quoted strings. strings. quoted Comments be inside . cannot //! //! Comments in JSL scripts */ Add Add sented by dt sented by summaries) (represented by obj by (represented maries) element data table reference data table reference column data scriptable object reference displayBox reference Doe family = List( John Doe, Jane Doe, Baby Doe ); Baby Doe, Jane Doe, John = List( family Doe }; Doe Baby Doe, Jane Doe, John = { family Doe 1 -1]; = [1 1, Matrix Design /* */ Symbol// Syntax Explanation a closing • as databy certain can be treated and manipulatedcomplex operators expressions—expressions • objects: to scriptable references basic elements in the language: • integers • point) (floating numbers • character strings •names • list holds a number lists—a value of other • associative arrays—an associative array mapskeys Generally the languagetokensGenerally translate into JSL data Comments code your thatyou add to notations Comments are •table of numbers matrix matrices—a is a row-by-column started by either Table 2.3 Note: Data elements Chapter 2 38 JSL Building Blocks Chapter 2 The JSL Language

• 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", <

Table 2.6 Messages for a Script Box Object ed << get line text(2) Places only the text from the designated line in a string. ed << set line text(2, "string") Removes the text currently in the designated line and replaces it with the string argument. ed << get line count() Returns the number of lines in the script window as an integer. ed << get lines(); Returns all the text in the script window as a list of strings, one line per string. ed << reformat(); Reformats the script. ed << run(); Runs the entire script in the script window.

The JSL Debugger In the JSL debugger, you can run the entire script, or step through the script one line at the time. To use the debugger, the first line of the JSL script should be /*debug run*/ or /*debug step*/ Make sure to type it exactly as shown above, in the first line of the script, with no extra blanks (includ- ing extra blanks within the comment). All letters must be lower case. 2 JSL Building Blocks 53 pauses when the line is pauses JSL Building Blocks Using the Script Editor and Debugger and Editor the Script Using d at the bottom of the debugger window. d at the bottom of the debugger window. that line, and the script time. A green arrow shows the current com- the current shows arrow A green time. Runs the script normally, without debugging withoutcommands. script normally, the Runs Removes a watchedRemoves variable. Adds a variable to the watch list, locate watch list, to the a variable Adds JSL Debugger Steps through the script one command at a script one command at through the Steps Runs the script from the current command. current the from the script Runs mand. Watched variablesthe script runs.values display their as Watched Remove Watch Run Without Debugger Step Run Add Watch the area to the left of a JSL line (the same area area a JSL line (the same of to the left in the area point to the script clicking by break a can add You appears at circle A red circulates). arrow the green where executed. Click the circle to remove the break point. the break the circle to remove Click executed. The following tasks are possible in the debugger. in possible tasks are following The Figure 2.7 Chapter 2 54 JSL Building Blocks Chapter 2 Help with JSL

Help with JSL There are several places within JMP to get help writing or understanding a JSL script.

JSL Browsers The Help menu has a sub-menu named Indexes for browsing operators, objects, and display boxes in the scripting language: Figure 2.8 Finding Information for JSL

JSL Operators Shows information about all general operators and functions. Object Scripting Shows scriptable objects and what messages each can interpret. DisplayBox Scripting Shows the elements in results windows and their messages. An entry in the JSL Functions Index includes the syntax and a brief explanation. Many entries also have example code. The Topic Help button for each entry opens the Help system and shows you the entry for the item in the “JSL Syntax Reference,” p. 437. See Figure 2.9 for the entry for If(). 2 JSL Building Blocks 55 : (for display (for Builtins Help with JSL (places all the information (places all the JSL Building Blocks DisplayBoxes StatTerms for all of the above. above. for all of the ote that some objects are not scriptable),not ote that some objects are All (the platforms and their messages), browser. The default argument (if none is browser. given) is Operators (which objects currently have instances), instances), have objects currently (which Scriptables lists all the scriptable objects and operators in the log window, producing a text report producing lists all the scriptable objects and operators in the log window, JSL Functions Index JSL Functions ---Class LayoutBox ---Class LayoutAtomBox ---Class ---Class ARIMA ---Class On] [Default [Boolean] Points Show On] [Default [Boolean] Interval Confidence Show [Action] Columns Save Only] [Scripting [Subtable] Columns ... Built-in Commands Built-in 7 Internal Add Internal 7 Subtract Internal 8 Multiply 8 Internal Divide ... show commands(DisplayBoxes); show show commands(scriptables); show show commands(); show in the Statistics Index into a JMP data table), Index and Statistics in the Other argumentsare ScriptableObjects Show Commands Show Figure 2.9 that is equivalent to the that is equivalent to tree objects and messages you can send to them—n can send objects and messages you tree Show Commands Chapter 2 56 JSL Building Blocks Chapter 2 Help with JSL

... ---Class TextBox Text Size [Enum] {7,9,10,12,14,18,24,Other...} Text Style [Enum] {Plain,Bold,Italic,Underline} Text Font [Enum] {Text,Heading,Title,Other...} Text Color [Color] ...

show commands(scriptableobjects); // objects that have instances Preferences Distribution Bivariate ... show commands(all); // all of the above Showing translations Use show commands(translations) for a list of all objects’ JSL commands in English and the localized language. This command creates a data table that lists commands, the English name, and the localized name. Argument translations are enumerated after their commands in entries beginning with the (localized) word Enumeration. For example, in the French release, submit the following to see translations of English JMP commands: show commands(translations); Figure 2.10 Localized Commands (French)

Show Properties Show Properties lists the messages that can be sent to a scriptable object, such as a data table, an analysis platform, or a display, producing a text report that is equivalent to the Objects browser. 2 JSL Building Blocks 57 Help with JSL JSL Building Blocks Close [Boolean] Close [Boolean] Horizontal [Action] Below All Open [Action] Below All Close ... Show Points [Boolean] [Default On] [Default [Boolean] Points Show Entity] [New Mean Fit Entity] [New Line Fit ... Tables [Subtable] Tables [Action] Summary [Action] Subset [Action] Sort Stack [Action] Split [Action] ... show properties(report(Bivariate[1])); //the platform's display tree display platform's //the properties(report(Bivariate[1])); show bivariate(y(weight),x(height)); //the analysis platform show properties(Bivariate[1]); Open("$SAMPLE_DATA/Big Class.jmp"); Open("$SAMPLE_DATA/Big table()); data properties(current show Chapter 2

Chapter 3 JSL Operators The basic functions in JSL

This chapter introduces JMP’s operators and their function equivalents. These are the same operators found in JMP’s formula calculator. In fact, the calculator window is driven behind the scenes by JSL. This section considers the calculator’s operators from a scripting perspective. For the precedence order of all operators, see Table 2.4 “Operators and function( ) equivalents, in pre- cedence order,” p. 38. For additional operators, see the “Advanced Concepts” chapter.

Confusion alert! Examples in this chapter occasionally use JSL features that haven’t been previously discussed. Do not worry too much about understanding every detail of an example—just focus on the general idea for the topic immediately under discussion. If you need more information about some other feature that is being used, you can consult the Help system, find quick overviews in the JSL browsers in the Index pane of the JMP Starter Window, or look it up in the “Index,” p. 651 of this book. You might also consider using Find while browsing the online books in Acrobat Reader. Contents 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 3 Operators 61 is 3 a for for JSL Operators ). For example, if ). For Numeric Functions ) and a functional equiv- ) a functional and ors to trigonometric and ors to + d numbers, matrices, and matrices, d numbers, JSL Syntax Reference Syntax JSL Assign is raised to the power of 2. of power raised to the is x — Power(x) . These operations are all operations are . These assignment operators om basic arithmetic operat om basic ion is assigned to the first argument. The most basic The most basic argument. ion is assigned to the first st be something capable of being assigned (an assigned something capable of being be st ws. Note that you can ad can you that ws. Note is a globala variable is whose value you can set. , because 3 is just a value and cannot be reassigned. You , because 3 is just a value and cannot be reassigned. You 3+=4 , because a , because ed statistical functions, see the chapter “Additional Numeric Oper- Numeric the“Additional statistical chapter functions, see ed operator (or the equivalent function operator (or the equivalent = a+=4 . If b is not provided— not b is . If are matrices, does matrix multiplication. matrix matrices, does are b b tions, and messages,” p. and tions, 437. are matrices, does matrix division. division. matrix does matrices, are for in-place arithmetic, or for b er. Each operator has two forms: an operator (e.g., an operator forms: two operator has Each er. becomes 7. and a a and . do something like do something a

. a . If . If ). . If , then ) ) b . b b by b from , , ) a b ) a a b by a+=4 a b , Add() to exponent power power exponent to and b and ) , ) a a a b a a ). You cannot You ). , a

Multiplies Multiplies Divides Raise Reverses sign of a Adds Subtracts b b b b b ^ a + – * / can, however, do something like can,however, done in place, meaning that the result of the operat done in place, meaning that the result JSL also provides operators operators JSL also provides assignment operator is the single Power( – a Minus( Add( Subtract( a Multiply( a Divide( a a The five essential arithmetic operators are as follo are arithmetic operators essential five The This This section lists and fr explains numeric functions, “Summary of operators, func variables that contain eith ators,” p.ators,” detailed in the also is sections this functions in 431. Each of the random functions. For more advanc more randomfunctions. For and you do The first argument to an assignment function mu function assignment an to argument first The L-value alent (e.g., Assignment operators Arithmetic operators Numeric Functions Chapter 3 62 JSL Operators Chapter 3 Numeric Functions

a=b Assign(a,b) Puts the value of b into a. a+=b AddTo(a,b) Add the value of b into a. Equivalent to a = a + b. a–=b SubtractTo(a,b) Subtract b from a, and assign to a. Equivalent to a = a - b. a*=b MultiplyTo(a,b) Multiply b with a, and assign to a. Equivalent to a = a * b. a/=b DivideTo(a,b) Divide b into a, and assign to a. Equivalent to a = a / b. a++ Post Increment(a) Adds one (1) to a, and assign to a. Equivalent to a = a + 1. Most often used as a loop control. a–– Post Decrement(a) Subtracts one (1) from a, and assign to a. Equivalent to a = a -1. Most often used as a loop control.

Constants JMP provides functions for two useful constants.

Note: These functions do not take an argument, but the parentheses are required.

e( ) Returns the constant e, approximately 2.7182818284590451. Pi( ) Returns the constant π, approximately 3.1415926535897931.

Additional numeric functions Abs(n) Returns a positive number of the same magnitude as the value of n. Ceiling(n) Returns the smallest integer greater than or equal to its argument n. 3 Operators 63 results in 2, in results results in 1. results evaluates as 10. . For example, . For . JSL Operators e is a synonym. is a synonym. is very small. n ) and is computed in the Ln , often denoted 5!, 5!, denoted often , Numeric Functions is Floor(2.7) places k” Modulo(6,5) is 5. Exp(1) choose n NChooseK(5,2) rounds to 3.56. rounds . The Log argument can be any numeric Factorial(5) Log(32,2) . For example, . For . An optional second argument lets you specify second argument . An optional lets you lGamma functions. is not The result always an ata time (“ k divisor you specify, e.g. specify, you . For example, . For . The argument n can be any numeric expression. expression. numeric any be n can . The argument ! n power . For example, . For n given by the second argument the given by – nk Round(3.555, 2) Round(3.555, () ! evaluates as 1, evaluates and as things taken things equal to its argument. For example, For argument. equal to its k logarithm) of n logarithm) is by divided n ), except that it is more accurate when accurate more that it is except ), () e ⁄ n ! defaultsroot. to 2 for square n r for the base 3 logarithm of n . ) Log(e()) n . , where , where ) n exponentiated to the Log(n,3) rounds to 3.55 and to 3.55 rounds inresults –1. ) divisor , root of ) divisor th ) k ) r , n , to the number of decimal places to the number of decimal n ) log(p/(1-p)) n r base ) ) ) number ) This is implemented internally in JMP using implemented internally in This is Floor(–.5) n n p n, places ) , n is a synonym. is , ) ) n n n n n number standard way using factorials, as factorials, way using standard evaluates as 120. a different base, e.g. e.g. base, a different productnumbers of all 1 through Returns This function the number returns of Returns the natural logarithmReturns (base (base 10) logarithm of common the Returns + as Log(1 result same the Returns Returns constant e the Returns Rounds 2) Round(3.554, of root square the Returns the Returns Returns the largest integer less than or Returns when number the remainder Returns Mod Note: integer. while while expression. The expression expression The expression. Log( NChooseK( Exp( Factorial( Log10( Log1P( Logit( Log( Sqrt( Root( Round( Modulo( Floor( Mod( Transcendental functions Transcendental Chapter 3 64 JSL Operators Chapter 3 Numeric Functions

Gamma(t) Returns the gamma function for t, or for each row in t if t is a column. Gamma is defined by:

∞ t – 1 –x Γ()t = ∫ x e xd 0 Solving this integral leads to: Γ()t + 1 ==tΓ()t t! (t factorial) and an interesting relationship is:

Γ()0.5 = π. LGamma(t) Returns the log gamma function for t, which is the natural log of gamma. You get the same result using the natural log function with the Gamma function; however, the Log Gamma function computes more efficiently and accurately than the pair. IGamma(t, shape) Returns the incomplete gamma function for t, which is the same as Gamma except the integral is incomplete and has a second shape parameter called a in the definition:

1 t a – 1 –x igamma()ta, = ------∫ x e xd Γ()a 0 The formula IGamma(Row(),1) uses the default shape parameter 1 and computes the incomplete gamma for each row using the row number as the limit of the integral. Digamma(n) Returns the digamma function evaluated at n. Trigamma(n) Returns the trigamma function evaluated at n. The trigamma function is the derivative of the digamma function. Beta(m, n) Returns the beta function which is written in terms of the Gamma function as Γ()Γm ()n B(m,n)= ------Γ()mn+ Arrhenius(n) Converts the temperature n to activation energy. Returns 11605/(n+273.15). Arrhenius Inv(n) The inverse of the Arrhenius function. Converts the activation energy n to temperature in Celsius. Returns 11605/(n-273.15). Scheffe Cubic(x1, x2) Returns x1*x2*(x1-x2). This function supports notation for cubic mixture models. Squash(expr) An efficient computation of the function 11⁄ ()+ eexpr , where expr is any numeric column, variable, or expression. The function is S-shaped and goes from 1 to 0 as its argument goes from minus infinity to infinity. 3 Operators 65 is a is is a synonym. ATan is a synonym. evaluates as evaluates ArCos JSL Operators Numeric Functions ArSin evaluates as 0.761594. evaluates as evaluates 0.549306. Tan(.25) is any numeric column, variable, column, variable, numeric is any is a synonym. TanH(1) evaluates as 0.46365. expr Cos is a synonym. is evaluates as evaluates 1.57080. Sin ArcTanH(0.5) , where , where evaluates as 1.175201. evaluates as 2.99322. 0 to 1 as its argument goes from minus infinity evaluates as 1.57080. expr evaluates as 0.881374. evaluates – e + evaluates1. as SinH(1) () ⁄ ArcTangent(0.5) 11 evaluates as 0. evaluates as 1.0. evaluates ArcCosine(0) ArcSine(1) ArcCosH(10) given in radians. The expression The expression in radians. given ArcSinH(1) all angle arguments radians. in Cosine(0) Sine(0) CosH(0) tangent. The expression tangent. The expression ) ) is a synonym. is ) ) ) ) ) ) expr ) Tan expr ) ) ) ) expr expr expr expr expr expr expr expr expr expr expr synonym. Returns the inverseReturns hyperbolic cosine. the inverseReturns hyperbolic Returns the inverse tangent. For example, inverse tangent.the Returns For sine. The expression hyperbolic the Returns the hyperbolic cosine. Returns The expression argument. tangent of its hyperbolic the Returns the inverseReturns hyperbolic sine. Returns the sine. For example, sine. For the Returns example, the cosine. For Returns tangent the of an argument Returns example, sine. the inverse For Returns example, For cosine. inverse the Returns An efficient computation of the function An efficient computation 0.255342. or expression. The function is S-shaped and goes from or expression. to infinity. ArcTanH( ArcSinH( ArcCosH( SinH( CosH( TanH( ArcCosine( ArcTangent( Tangent( ArcSine( JMP’s trigonometric functions expect trigonometric JMP’s Sine( Cosine( Squish( Trigonometric Functions Trigonometric Chapter 3 66 JSL Operators Chapter 3 Numeric Functions

Random Functions Random functions generate random numbers. The basic random functions are briefly listed below. For more advanced random functions that generate random numbers from various distributions, see “Ran- dom Functions,” p. 455 in the Syntax Reference. Random Functions Col Shuffle( ) Shuffles the values randomly each time evaluated. Takes no arguments, but parentheses are required. Random Shuffle(m) Returns the matrix m with the elements shuffled into a random order. Random Reset(seed) Restarts the random number sequences with seed. Random Uniform() Random Uniform(x) Random Uniform(high, low) Generates random numbers uniformly between 0 and 1. This means that any number between 0 and 1 is as likely to be generated as any other. The result is an approximately even distribution. You can shift the distribution and change its range with constants. No argument is expected, but the parentheses are required. For example: Random Uniform(x) generates numbers between 0 and x. Random Uniform (high,low) generates numbers between low and high. Random Normal() Generates random numbers that approximate a normal distribution with mean 0 and variance 1. The normal distribution is bell shaped and symmetrical. Random Integer(n) Random Integer(k,n) Returns a random integer from 1 to n or from k to n. Random Exp() Returns a random number distributed exponentially from 0 to infinity. Equivalent to the negative log of Random Uniform. This function takes no argument. Random Index(n,k) Returns a k by 1 matrix of random integers between 1 and n with no duplicates. Resample Freq() See below for a discussion of the Resample Freq function. Note that the below functions have been deprecated: • Random Seed • Random Seeded Normal • Random Seeded Uniform 3 Operators 67 JSL Operators is already open. is already Character Functions Character Big Class.jmp s a random selection with replacement with s a random replacement selection frequency sample frequency *nrow d return character strings, althoughsome taked return otstrapthe error of distribution the standard of low. Further details of some of these functions functions some of these of details Further low. that expected value), but varythat expected value), but somewhat due to nts that are literal character literal thatntsare strings must be generates a resample with respect to an existing fre- to generatesrespect with resample a ) y column will a produce new column frequency whose fraction frequency sample frequency randomly selected rows. n ponding to the old frequency column. ponding to the old frequency It assumes the sample data file the assumes data file sample It FreqColumn generates , ) n

or

generates 100% resample generates an function forcolumn function formulas generate ) fraction n fraction Freq(:Resample),Fit Line); Freq(:Resample),Fit newColumn("StdErr",numeric)); Resample Freq Resample quency column se1 = (obj<

Other related functions are discussed in “Hexadecimal and BLOB Functions,” p. 429 in the “Advanced Concepts” chapter. For more information on using patterns and regular expressions, see “Pattern Matching and Regular Expressions,” p. 412 in the “Advanced Concepts” chapter. Character Functions Char(Expr(expr)) Char(name) Char(number, width, decimal) Converts an expression or numeric value into a character string. The expression must be quoted with Expr(); otherwise its evaluation is converted to a string. Width and decimal are optional arguments for formatting numbers; the default is 18 for width and 99 for decimal. The formatted value is fit to the specified width, with leading blanks trimmed so that the number may be less than the specified width. A special code of -1 (the default) can be used to represent whatever width is needed to represent the number. Since floating point numbers are represented with roughly 17-digit precision, the default width does not exceed 24 characters, allowing positions for sign, decimal point, and scientific “E” suffix. Num("string") Produces a numeric value that corresponds to its character string argument when the character string consists of numbers only. If a character string contains a non-numeric value, the result is a missing value. For example, Num("1.123") evaluates as the number 1.123. Uppercase("text") Converts any lower case character found in its argument to the equivalent uppercase character. Lowercase("text") Converts any upper case character found in its argument to the equivalent lowercase character. a||b Concat(a,b) Returns the second string appended to the first. For example, "Dr."||" "||name produces a new string consisting of the title “Dr.” followed by a space and the contents of the name string. See “Concat,” p. 71 for more details. Set Clipboard(arg) Evaluates the argument, looking for a character result, which is then placed on the clipboard. Substr("text", start, length) Extracts the characters that are the portion of the first argument beginning at the position given by the second argument and ending based on the number of characters specified in the third argument. The first argument can be a character column or value, or an expression evaluating to same. The starting argument and the length argument can be numbers or expressions that evaluate to numbers. For example, to show the first name only, Substr("Katie Layman", 1, 5); starts at position 1, reads through position 5, and ignores the remaining characters, which yields 3 Operators

69 JSL Operators Length("Elizabeth") Character Functions Character in the optionalin second argument. The the delimiters given as the optional third the delimiters given as the optional third the optional third the delimiters given as clude a third argument,alland anyin charactersclude a third clude a third argument,alland anyin characters clude a third argument,any and all characters in that argument treats each delimiter character as a separate delimiter, and eacha delimiter character as separate delimiter, treats treats each delimiter character as a separate delimiter, and eacha delimiter character as separate delimiter, treats argument, removing any trailing anyblanks. argument, removing ters) of its argument. For example, ters) of its argument. For Item Item ") ") ") according to the according delimiters listed values past the end of the string, result in an empty string. empty in an result string, past the end of the values except that except except that except text start delimiters delimiters Word Item delimiters item a from character string,to according word from a character to from according string, word ") ", " ") ", " ") th th values, or n n "," ") text text text text start " " text " " text is thesame as adjacentseveral delimitersas a singledelimiter. treats is thesame as adjacentseveral delimitersas a singledelimiter. treats text n, n, n, n, n, n, "fox" {"Doe","Jane","P"} "brown" "fox" {"the","quick","brown","fox"} "brown" evaluates as 9. Word(4,"the quick brown fox"); brown quick Word(4,"the are taken to are be delimiters. ."); P.",", Jane Words("Doe, fox"); brown quick Item(4,"the Calculates the length (number of charac Word(4,"the quick brown fox"); brown quick Word(4,"the a include second default delimiter you is space; if fox"); brown quick Words("the the Extracts Item Word Word(2, "Katie Layman"); //returns //returns "Layman." "Katie Layman"); Word(2, Word Word fox"); brown quick Item(4,"the from Extracts the words “Katie.” Missing new a character stringits from Produces Extracts the argument. The default delimiter is space; if you in if you space; delimiter is default The argument. takenbedelimiters. to are that argument argument. The default delimiter is space; if you in if you space; default delimiter is The argument. takenbedelimiters. to are that argument Trim(" Word( Word( Length(" Item( Item( Words(" Chapter 3 70 JSL Operators Chapter 3 Character Functions

Contains("whole", "part") Contains(string1, string2) Contains(list, list item) Contains(matrix, n) Returns the numeric position within the first argument of the first instance of the second argument, if it exists. If the second argument is not found within the first argument, a zero is returned. Left(string, n) Left(string, n, filler) Returns a truncated or padded version of the original string. The result contains the left n characters padded with any filler on the right if the length of string is less than n. Also works for lists. Right(string, n) Right(string, n, filler) Returns a truncated or padded version of the original string. The result contains the right n characters padded with any filler on the left if the length of string is less than n. Also works for lists. Starts With(string, substring) Returns 1 if the if substring appears at the start of the string. Ends With(string, substring) Returns 1 if the if substring appears at the end of the string. Munger("text", offset, find/length) Munger("text", offset, find, replace) Computes new character strings from text by inserting or deleting characters. It can also produce substrings, calculate indexes, and perform other tasks depending on how you specify its arguments. Offset is a numeric expression indicating the starting position to search in the string. If the offset is greater than the position of the first instance of the find argument, the first instance is disregarded. If the offset is greater than the search string’s length, Munger uses the string’s length as the offset. See “Munger,” p. 72 for more details. Repeat(source, a) Repeat(matrix, a, b) Return a copy of source concatenated a times, or return a matrix composed of a row repeats and b column repeats. See “Repeat,” p. 72 for more details. Sequence(from, to, stepsize, repeatTimes) Produces an arithmetic sequence of numbers across the rows in a data table, where the from and to are specified. stepsize and repeatTimes are optional; they both default to 1. See “Sequence,” p. 73 for more details. 3 Operators 71 on the global itemseparated by a JSL Operators Character Functions Character Name Expr Name single string, witheach ted like character strings, but globals that example demonstrates that if you have a stored a stored have you if that example demonstrates ngs (as well as lists and matrices). as ngs (as well before storing it in a global, or storing before Char converts a list of string expressions into a into expressions a list of string converts function searches character stri character function searches function, expressions yielding names are trea are names yielding function, expressions Concat Contains “ABC DEF HIJ” DEF “ABC item) (string, Contains item) Contains(matrix, item) Contains(list, “Jaclyn”}; “Jane”, “Louise”, nameList={“Katie”, “Katie”); = Contains(nameList, r resultString = Concat Items ({list of strings}, <“delimiter string”>); <“delimiter strings}, of ({list Items Concat = resultString “HIJ”}; “DEF”, = {“ABC”, a “/”); Items(a, Concat = result “ABC/DEF/HIJ” Items(a); Concat = result n = { abc }; { abc = n "def"; || c=n[1] show(c); is "abcdef" //result m=expr(mno); "xyz"; = m || c show(c); is unresolved mno that message error is an //result m = expr(mno); "xyz"; || Expr(m) = Name c show(c); is "mnoxyz" //result m=char(expr(mno)); || "xyz"; c=m show(c); is "mnoxyz" //result name. Concat Items() Concat The The example, For Alternatively, returns For example, For returns Concat In the have the name values will be evaluated. The following use to either need you value, name delimiter. If unspecified, the delimiter is a blank. Its syntax is unspecified, If the delimiter is a blank. Its delimiter. Chapter 3 72 JSL Operators Chapter 3 Character Functions

returns a 1.

Munger Munger works many different ways, depending on what you specify for its arguments: Munger(string, offset, find | length, ); Table 3.1 Munger behaviors for various types of arguments Find, length, and replace arguments Example If you specify a string as the find and specify no Munger("the quick brown fox", 1, replace string, Munger returns the position (after "quick"); offset) of the first occurrence find string. 5 If you specify a positive integer as the length and Munger("the quick brown fox",1,5); specify no replace string, Munger returns the char- "the q" acters from offset to offset + length. If you specify a string as the find and specify a Munger("the quick brown fox", 1, replace string, Munger replaces the first occurrence "quick", "fast"); after offset of text with replace. "the fast brown fox" If you specify a positive integer as the length and Munger("the quick brown fox", 1, 5, specify a replace string, Munger replaces the char- "fast"); acters from offset to offset + length with replace. "fastuick brown fox" If you specify a positive integer as the length, and Munger("the quick brown fox",5,25); offset + length exceeds the length of text, Munger "quick brown fox" either returns text from offset to the end or replaces Munger("the quick brown fox",5,25, that portion of text with the replace string, if it "fast"); "the fast" exists. If you specify zero as the length and specify no Munger("the quick brown fox", 1, replace string, Munger returns a blank string. 0); "" If you specify zero as the length and specify a Munger("the quick brown fox", 1, 0, replace string, the string is inserted before the offset "see "); position. "see the quick brown fox" If you specify a negative integer as the length value Munger("the quick brown fox", 5, and specify no replace string, Munger returns all -5); characters from the offset to the end of the string. "quick brown fox" If you specify a negative integer for length and Munger("the quick brown fox", 5, specify a replace string, Munger replaces all charac- -5, "fast"); ters from the offset to the end with the replace "the fast" string.

Repeat The Repeat function makes copies of its first argument into a result. The second (and sometimes a third) argument is the number of repeats, where 1 means a single copy. If the first argument evaluates to a character value or list, the result is that many copies. repeat("abc",2) "abcabc" 3 Operators 73 and from = 4 = from with the above with the above JSL Operators Stepsize increments the increments Stepsize Character Functions Character s one more time than this func- time than s one more 4, 4, 4, 6, 6, 6, 8, 8, 8, 4, ... If 8, 4, ... 8, 8, 6, 6, 4, 4, 6, 4, repeat = 3 = repeat values, the cells will be filled with the cells values, to rmula and Editor is used to fill the cells in and the same name in the SAS/IML language,insame name the but the defaultvalue is 1. from e default value is 1. Repeat specifies how many e specifies how is default 1. Repeat value , the result is a matrix. The , second argument is the the result e of values to place into the cells. If ecify the number of column repeats. If only two only If repeats. ecify the numberof column values 4, 5, 6, 7, 8, 4, ... 4, 6, 7, 8, 5, values with the above the above with ter data step function, which repeat mber is 1. of column repeats values, the cells will be filled with the values will be filled with values, the cells stepsize = 2 = stepsize stepsize corresponds to the Sequence function in the Fo to the Sequence corresponds are not optional. They specify are the rang function is compatible with the function of the compatible with is function is optional. If you do not specify a stepsize, a stepsize, not specify do you optional. If is to 3 4 3 4 3 4, 3 4 4 3 1 2, 1 2 2 1 3 4] 4 3 4 3 9 9 9] , and , the cells will be filled with the , the cells will be filled do th is you not optional. If specify a Repeat, to 17, ... */ ... 17, [1 2, 2 1 2 1 {1,2,3,1,2,3} {"A","A"} [ 9 9 9, and , repeat for each row ( each for // Create a new data table data a new Create // Example"); Table("Sequence = New dt 50 rows and columns Add 2 // Five"); to Column("Count << New dt (50); Add Rows dt << by Fours"); Seventeen to Column("Count << New dt 5, ... 4, 3, 2, 1, sequence data with the column the first Fill /* 17, 13, 9, 13, 9, 5, 1, 5, 1, sequence data the with column second the Fill Sequence(from, to, stepsize, repeat) to, stepsize, Sequence(from, repeat([1 2, 3 4],2,3) 2, 3 repeat([1 repeat({1,2,3},2) repeat({"A"},2) repeat(9,2,3) tion. Sequence times each value is repeated before incrementing to the next value. If If next value. to the incrementing before repeated is each value times From Stepsize Repeat from Sequence() = 8 to The The If the first argument evaluates to a number or matrixor the first argumentnumbera evaluates to If can sp argument third a and repeats, number of row the nu specified, are arguments the values 4, 6, 8, 4, 6, ... you specify a Repeat value, you must also specify a Stepsize value. Stepsize a must also specify you value, Repeat a specify you eachfilled.the column untilThe sequence is alwaysin cell is repeated Example: a data table column. It takes four arguments and the last two are optional:takesand four arguments the last two are column.It a data table is incompatible with the SAS charac values in the range. If range. If in the values Chapter 3 74 JSL Operators Chapter 3 Comparison and Logical Operators

column(1)[ ] = Sequence(1,5); column(2)[ ] = Sequence(1,17, 4, 2); ); Since Sequence() is a formula function, you can also set a column's formula to use Sequence to fill the column. This example creates a new column named “Formula Sequence” and adds a formula to it. The formula is a sequence that fills the column with values between 25 and 29, incremented by 1, and repeated twice (25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 25, ...). dt << new column("Formula Sequence", formula(Sequence(25, 29, 1, 2))); Examples of Sequence results: Sequence(1,5) produces 1,2,3,4,5,1,2,3,4,5,1, ... Sequence(1,5,1,2) produces 1,1,2,2,3,3,4,4,5,5,1,1, ... Sequence(10,50,10) produces 10,20,30,40,50,10, ... 10*Sequence(1,5,1) also produces 10,20,30,40,50,10, ... Sequence(1,6,2) produces: 1,3,5,1,3,5, ... The limit is never reached exactly. Note: If you want a matrix of values, then use the Index function, not Sequence.

Comparison and Logical Operators The comparison operators (<, <=, >, >=) work for numbers, strings, and matrices. For matrices they produce a matrix of results. If you compare mixed arguments, such as strings with numbers or matrices, the result is a missing value. Comparisons involving lists are not allowed and also return missing values. The equality operators (== and !=) work for numbers, strings, matrices, and lists. For matrices, they produce a matrix of results; for lists, they produce a single result. If you test equality of mixed results, e.g. strings with numbers or matrices, the result is 0 or unequal. Range check operators let you check whether something falls between two specified values: a=1;show(1<=a<3); b=2;show(2

Comparison operators a==b Equal(a,b) Returns 1 if all arguments evaluate to the same value, otherwise 0. Missing values propagate. Case-sensitive for string comparisons. 3 Operators 75 ), ), c ), otherwise 0. c ), otherwise 0. c gical Operators JSL Operators ), otherwise 0. Missing c Comparison and Comparison Lo evaluates greater than or equal to or equal than evaluates greater b evaluates less than or equal to evaluates strictly greater thanstrictly evaluates greater b b results than the more usual method usual of evaluating than the more results (and (and evaluates strictly less than b b Useful for flaggingthat couldhave been values Useful (and (and . That means JMP treats arguments compar-. That means joined by JMP treats (and b b (and (and e evaluated all at once, not in sequence not at once, all evaluated e ) b , eliding operators ) ) ) c c , , ) ) b b b b,c c , , , , , a a a a LessorEqual(a ) b ) , ) c c b evaluates than orgreater equal to evaluates less than or equal to evaluates strictly greater than evaluates strictly less than b a a a ) , expr , b b >= a c; , , b b<=c; > a a ); Less(a,b,c) b >= b <= > , c c a >= < <= != Less LessEqual( LessEqual Less( Greater( Greater( GreaterorEqual( GreaterorEqual( Less( LessorEqual(a a Is Missing( Zero or Missing(expr) a a a a a Expressions with comparison operators ar with comparison Expressions are All the comparison operators way most expressions are evaluated one operator at a evaluated are to the way most expressions as opposed big clause, operators as one ison as a single different clausetime. produces Evaluating different: statements are two example,the following For in pieces. Not Equal( a Chapter 3 76 JSL Operators Chapter 3 Comparison and Logical Operators

12

Logical operators JSL provides the usual logical operators—And, Or, and Not. These are most often used for compound comparisons, e.g. if( sex=="M" & operation=="hysterectomy", print(row()) ); a & b And(a,b) Logical And. Returns 1 if both are true, missing if any are missing, and 0 otherwise. a | b Or(a, b) Logical Or. Returns 1 if either or both are true, missing if any are missing, and 0 otherwise. !a Not(a) Logical Not. Maps nonzero values to 0, maps zero values to 1, and leaves missing values missing.

Special cases Here are some examples to show what you should expect for comparisons involving missing values, mismatched types, and matrices.

Table 3.2 Some special-case comparison tests Test Result Explanation m=.; m==1 . Equality test with missing returns missing. m=.; m!=1 . Inequality test with missing returns missing. m=.; m<1; m>1; etc. . Any comparison with missing returns missing (unless it couldn’t possibly be true, see next). m=.; 1

77

And any

-MZ testto be true, ). These test needs to be true be true to needs test AND gical Operators JSL Operators OR arisons; it returns 1 if arisons; it returns MatchMZ matrix of elementwise results. results. of elementwise matrix s matrix of elementwise results. s matrix of elementwise results. and IfMZ Comparison and Comparison Lo (and (and lue) than or equal to a missingvalue,is greater be, but you don’t know for sure, so the result is for so the result sure, know be, but you don’t a known value? Sometimes it is possible to deter- it is Sometimes value? a known OrMZ ations. Two exceptions: exceptions: Two operations. and logical mparisons don’t know, so the result is missing. Likewise, you you missing. Likewise, is the result so know, don’t s work: Suppose you have survey data and some surveyand data have you Suppose s work: erting v. formulas from 3 data tables. and returns true; returns if one value is false and the other missing, now handle now missing values differently than in JMP summarizes elementwise comparisons; it returns 1 only all if elementwise comparisons; it returns summarizes summarizes elementwise comp AndMZ Or Or ). Previously missing values returned false results; now now false results; returned values missing Previously ). Missing evaluates to False, because for an evaluates Missing to False, comparisons are true and returns 0 otherwise. true and returns are comparisons comparison is true and returns 0 otherwise. truecomparison is and returns Equality test of list arguments returns a single result. single result. a Equality of list test arguments returns is not allowed. arguments Comparison test of list false. returns types with mixed Equality test missing. returns types mixed Comparison with 0 otherwise. 1 if missing, Returns Equality test of matrices return done ele- is comparison to a matrix, compared is When a matrix and 0s. a matrix of 1s returns and ment-by-element If a matrix is 2s. and a matrix filled with matrix of test Equality matrix filled a as treated the number is number, a to compared with that number. Comparison of matrices returns Comparison of matrix and a matrix filled with 2s. All Any AND and Match And and and If Logical Missing evaluates to True, because only one thing in an toTrue, evaluates Missing Result Explanation 0 . OR Some special-case comparison special-case comparison tests (Continued) Some they propagate missing values, as discussed here. here. as discussed values, missing they propagate the v.For you can use 3 behavior, operators are used automatically when conv are operators Confusion alert! alert! Confusion version 3.x (as do [1 2 3] < [2 2 5][1 2 3] < 2[1 1] 0 [1 All([2 2]==[1 2]) Any([2 2]==[1 2]) 0 0] [10 1 IsMissing(m)[1 2 3]==[2 2 5] 1 [0 1 0] [1 2 3]==2 [0 1 0] Test {a, b}==list(a, b){a, b}<{a, c} 1 1=="abc" 1<="abc" . for the result to be true. for the result so the result is missing. is missing. so the result value a missingWhat aboutwhen you compare with False example, For result. mine the missing. Are they not Are gender? Again, you the same missing. cannot know whether some value (including a missing va respondents didn’t specify gender, male or female, so you have missing values. Now you compare two two compare you Now values. missing have so you female, male or gender, specify didn’t respondents they the same Are gender? missing values. They might returns false. value missing how way to remember easy an Here’s

Missing values propagate missing values for most missing co values propagate values Missing if one value is trueif one value and another missing, Table 3.2 both things must be true. Since one thing is False, it doesn’t matter what the other is—the result will be whatthe other is—the matter result it doesn’t both things must be true.thing one is False, Since True false. Similarly Missing values Chapter 3 78 JSL Operators Chapter 3 Comparison and Logical Operators

If you prefer to see truth tables, submit this script: T=[0 0 0 1 1 1 . . .]`; U=[0 1 . 0 1 . 0 1 .]`; show(T==U, T!=U, TU, T>=U, -T,!T, T&U, T|U, T+U); T == U:[1,0,.,0,1,.,.,.,.] T != U:[0,1,.,1,0,.,.,.,.] T < U:[0,1,.,0,0,.,.,.,.] T <= U:[1,1,.,0,1,.,.,.,.] T > U:[0,0,.,1,0,.,.,.,.] T >= U:[1,0,.,1,1,.,.,.,.] -T:[0,0,0,-1,-1,-1,.,.,.] !T:[1,1,1,0,0,0,.,.,.] T & U:[0,0,0,0,1,.,0,.,.] T | U:[0,1,.,1,1,1,.,1,.] T + U:[0,1,.,1,2,.,.,.,.] You cannot make comparisons directly with explicit missing values—only with variables, matrices, or other things, which could contain missing values. For direct comparisons, use Is Missing or Zero Or Missing: a==.; a<=.; // produce errors - you should use IsMissing(a) IsMissing(a); // returns 1 when a is missing b=.;a==b; a<=b; // does the comparisons ZeroOrMissing(a); // returns 1 when a is missing or a is zero

Missing character values Only numeric missing values are considered to be missing values. Missing character values are consid- ered to be strings of zero length, not missing values, so you would use a test such as a=="" rather than Is Missing(a).

Short-circuiting behavior JMP’s comparison and logical operators are short-circuiting operators—they stop working as soon as they can return a result. Usually this produces the results you expect, but you should be careful in the follow- ing circumstances. When a later argument depends on an earlier argument For example, in this expression, List[50] will not even be examined unless the list actually has at least 50 elements: n items(list)>=50 & list[50] == 10; When lengthy calculations pose performance concerns Suppose you have an accurate measurement function which is slow, but an approximate version which is fast. You might consider doing a quick, rough comparison first and then running the lengthy test only when the quick test’s result crosses a certain threshold: est(x)<.05 & acc(x)<0.01; 3 Operators 79 Day Of Day Of , JSL Operators Date/Time Operators Date/Time Day Of Week Day rge numbers. For example For rge numbers. , to get a format: recognizable Year , Day nce midnight, January 1, 1904. nce midnight, January , Long Date Long Month If it were the stroke of midnight, 1midnight, of stroke the it were If December column to label rows, or any other case where you or any other case where to label column rows, should be appropriately la be appropriately should equivalent. 3153081600, Each wouldreturn and you , which all return integers. For example: For integers. , which all return to zero, since the indicated date is the base date or “zero date” date” baseor “zero datedate is the indicated since the to zero, x ally as numbers of seconds si of seconds numbers as ally will set Time Of Day Of Time , and x=01Jan1904 x=01Jan1904 rts of dates happens to be 2990390400. Week Of Year Week Of 335 "Monday, December 1, 2003" 1, December "Monday, 3153081600 , day of year(today()); day long date(today()); long DMY(row(),3,2001))); format("m/d/y"),formula(Date date", column("Entry new machine on your is available pick you format the be sure // Date DMY(1,12,2003); DMY(1,12,2003); Date MDY(12,1,2003); Date Today(); in JMP. If you examine the values of dates, they the values examine you If in JMP. Year can describe a series of date values generally: date values of a series can describe You can extract partsoperators using the of date values You 2003, all of the following statementstheof following all2003, would be any of themto a date notationpass could operator such as a date setting up are you handy if operators are These You canoperators. construct dates with the following You Date/time data are handled intern Date/time data are 5oct98 When you depend upon later arguments being executed being upon later arguments depend When you example, that might for part in a of an expression statements, assignment placing about careful Be be executed. never expression The Extracting pa Constructing dates Constructing Date/Time Operators Chapter 3 80 JSL Operators Chapter 3 Date/Time Operators

Confusion alert! Because Sunday is the first day of the week, the first Sunday of each year always starts week 2. Days before the first Sunday (if there are any) will be in week 1. This means that in a year in which January 1 is on Sunday, the first week is counted as the second week. Example: Week of Year(Date DMY(1,1,2006)); 2 In years in which Sunday is the first day of the year, subtract 1 from Week Of Year() to obtain the correct week number.

Arithmetic on dates You can perform the usual arithmetic operations with date/time data as with any other numeric data. For example, you could find the days elapsed between entries: new column("Days elapsed", formula( if(row()==1,., //to avoid error for row 1 //else for rows after 1: (:Entry date[row()]-:Entry date[row()-1])/in days())));

Converting date/time units The In Minutes, In Hours, In Days, In Weeks, and In Years operators are useful for re-express- ing a time interval in units other than seconds. For example, this returns the number of fortnights between now and the next Leap Day. (Date DMY(29,2,2004)-Today())/InWeeks(2); Usually n is 1, but you could use In Years(10), for example, to re-express an interval in decades.

Y2K-ready date handling JMP uses its own Y2K-ready algorithms for interpreting and displaying date/time strings rather than supporting operating system-specific date/time formats. JMP respects the date/time separator-charac- ters chosen in the Regional Settings control panel (Windows) or the Date&Time control panel (Macin- tosh) for interpreting and displaying dates. JMP always displays four-digit years regardless of Regional Settings. If for some reason it should be nec- essary to show two-digit years, use JMP’s operators for manipulating character strings. Two-digit years are interpreted according to the current system clock year, according to the rules below. To avoid ambiguity or override the default interpretation, type a four-digit year value. 3 Operators 81

) / argu- Result format 149 in the “Data “Data in the 149 JSL Operators Date/Time Operators Date/Time Locale Date Time h:m:s Time Date Locale entering date/time values in entering date/time values , type 5 in year 1991 2005 type 13 in year 2024type 13 in year 2013 Examples type 99 in year 2015type 99 in year 2099 type 5 in year 1979 1905 type 99 in year 1999type 99 in year 1999 on your machine might differ from the machine might differ from on your Locale Date Time h:m Locale Date Time , be displayed in a text window (like the log window) be displayed (like the log window) in a text window current century current 1988 type 13 in year 1913 19__ 19__ itarydesignators. AM/PM time) or with in Tablefor the can also use them 3.4. You operators for displaying and operators for displaying . For example, . For Locale Date Locale As Date InFormat rding to your regional settings. regional to your rding and and Format message to a data column, as discussed in “Display formats,”message column,to a data as discussed in “Display p. after 1990 (Mac) before or duringbefore 1990 (Mac) duringor after 1990 (Win) 20__ . Note that the date-separator that the character . Note time values in 24-hour(mil format How JMP interprets two-digit years JMP interprets How Format 10Dec2000 "01/02/1999 12:00:00 AM" 12:00:00 "01/02/1999 "Jan 2, 1999" 2, "Jan 02Jan1999:13:01:55 "Saturday, January 2, 1999" 2, January "Saturday, ":35839:19:15" "01/02/1999" mdyhms(2998080000); abbrev date(2998080000); abbrev h:m:s"); 13:01:55","ddMonyyyy InFormat("02Jan1999 long date(2998080000); long Format(3096558900,":day:hr:m"); + inDays(2)); = As Date(8Dec2000 x short date(2998080000); short 91–99(Mac) duringor after 2011 20__ 11–89(Win) 11–90(Mac) time any 90–99(Win) 2011 before What you typeWhat is evaluated When it 00–10 Result 1990 (Win) before Tables” chapter characterhere. shown You may enter Table 3.3 ment to a The formats JMP supports currently shown are Dates that are the results of expressions that are to that are of expressions results the Dates that are as shows You can also use the can use also You given asare a date attribute using Several operators convert numbers directly to common formats. to convert numbers directly operators Several Note that three locale-specific formats ( formats locale-specific that three Note one of many notation formats. notation one of many always display the date time acco date the always display Date/time notation Chapter 3 82 JSL Operators Chapter 3 Date/Time Operators

Table 3.4 Date/time formats supported in JMP Type Format string Example Date only "m/d/y" "01/02/1999" "mmddyyyy" "01021999" "m/y" "01/1999" "d/m/y" "02/01/1999" "ddmmyyyy" "02011999" "ddMonyyyy" "02Jan1999" "Monddyyyy" "Jan021999" "y/m/d" "1999/01/02" "yyyymmdd" "19990102" “yyyy-mm-dd” “1999-01-02“ Date and time "m/d/y h:m" "01/02/1999 13:01" "01/02/1999 1:01 PM" "m/d/y h:m:s" "01/02/1999 13:01:55" "01/02/1999 1:01:55 PM" "d/m/y h:m" "02/01/1999 13:01" "02/01/1999 1:01 PM" "d/m/y h:m:s" "02/01/1999 13:01:55" "02/01/1999 1:01:55 PM" “y/m/d h:m” ‘1999/01/02 13:01’ ‘1999/01/02 1:01 PM’ “y/m/d h:m:s” ‘1999/01/02 13:01:02 ‘1999/01/02 1:01:02 PM’ "ddMonyyyy h:m" "02Jan1999 13:01" "02Jan1999 1:01 PM" "ddMonyyyy h:m:s" "02Jan1999 13:01:02" "02Jan1999 1:01:02 PM" "ddMonyyyy:h:m" "02Jan1999:13:01" "02Jan1999:1:01 PM" "ddMonyyyy:h:m:s" "02Jan1999:13:01:02" "02Jan1999:1:01:02 PM" "Monddyyyy h:m" "Jan021999 13:01" "Jan021999 1:01 PM" "Monddyyyy h:m:s" "Jan021999 13:01:02" "Jan021999 1:01:02 PM" Day number ":day:hr:m" "34700:13:01" and time ":33:001:01 PM" ":day:hr:m:s" "34700:13:01:02" ":33:001:01:02 PM" "h:m:s" "13:01:02" "01:01:02 PM" 3 Operators 83 JSL Operators minutes, hours, days, minutes, hours, days, n Date/Time Operators Date/Time , “01/02/1999 13:01:02“ or “01/ s fifty two days, three hours, one hours, two days, three s fifty y seven minutes and 4 seconds. minutes y seven as the number seconds since of mid- as the number seconds since of mid- nd Leap Day of the second millen- nd Leap Day of the second millen- nd Leap s on the locale setting for setting for your operating locale s on the setting for your operating locale s on the setting for your operating locale s on the , 3160857600.which returns , 3160857600.which returns e number of seconds per “52:03:01:30”, read which seconds. and thirty minute, minutes. and 4 seconds. minutes, system. States, “01/02/1999" For the United system. For“01/02/1999 the United States, 13:01“ or “01/02/ 1999 01:01PM“ States United the For system. 02/1999 01:01:02 PM“ "01:02 PM" 1999-01-02T13:01:02 minute. “37:04”, thirt which reads "13:01" one and hours, three days, two reads fifty which “52:03:01”, seven thirty hours, reads seventeen which “17:37:04”, “17:37”, which reads seventeen hours and thirty seven and thirty hours seventeen reads “17:37”, which (Display only) "Saturday, January 2, 1999" (Display only) "Saturday, Depend only) (Display (Display only) 2, 1999" "Jan ats are not availableats for date input. are DateMDY(2,29,2004) DateDMY(29,2,2004) weeks, or years. Divide by these to re-express an interval as an in seconds to re-express these by Divide or years. weeks, intervalunits. other in Returns the specified date, expressed expressed specified date, the Returns niumis expressed specified date, the Returns niumis the numberas of seconds expressed and date time current the Returns arguments accepted, butthe are 1904. sincemidnight, 1 January No still needed. are parentheses These operators return th These operators return 1904, e.g. the seco night, 1 January 1904, e.g. the seco night, 1 January Explanation ) ) year year , , day "Date Abbrev" "Date “hr:m“ “hr:m:s“ “min:s” h:m” Time Date “Locale Depend only) (Display h:m:s” Time Date “Locale Depend only) (Display “yyyy-mm-ddThh:mm”“yyyy-mm-ddThh:mm:ss” 1999-01-02T13:01 “:day:hr:m:s“ “h:m” , month, ) ) month day n Date/time operators Date/time formats supported JMP in (Continued) ) n ) ) n n n Locale Date Date” “Locale Abbreviated Abbreviated date Long dateLong Long" "Date Locale Date Locale Date Time Date MDY( Date Today() In Hours( In Days( In Operator In Minutes( In Weeks( In In Years( In DMY( Date Type Format string Example Duration “:day:hr:m“ Note that the last five date/time form that the last five Note Table 3.5 Table 3.4 Chapter 3 84 JSL Operators Chapter 3 Date/Time Operators

Table 3.5 Date/time operators (Continued) Operator Explanation Second(datetime) Returns an integer representation for the second part of the date-time value supplied. Minute(datetime) Returns an integer representation for the minute part of the date-time value supplied. Hour(datetime) Returns an integer representation for the hour part of the date-time value supplied. Day(date) Returns an integer representation for the day of the month of the date supplied. Month(date) Returns an integer representation for the month of the date supplied. Year(date) Returns an integer representation for the year of the date supplied. Day Of Week(date) Returns an integer representation for the day of the week of the date sup- plied. Weeks are Sunday–Saturday. Day Of Year(date) Returns an integer representation for the day of the year of the date sup- plied. Week Of Year(date) Returns an integer representation for the week of the year of the date sup- plied. Weeks are Sunday–Saturday. Note that the first Sunday of the year begins week 2. Time Of Day(date) Returns an integer representation for the time of day of the date/time sup- plied. Short Date(date) Returns a string representation for the date supplied, in the format mm/ dd/yy, e.g. "02/29/04". Long Date(date) Returns a string representation for the date supplied, formatted like "Sunday, February 29, 2004". Abbrev Date(date) Returns a string representation for the date supplied, formatted like "Feb 29, 2004". MDYHMS(date) Returns a string representation for the date supplied, formatted like "2/ 29/04 00:02:20". Format(date, "format") Returns the value in the format you specify in the second argument. Most typically used for formatting date/time values from a number of seconds to a formatted date. Format choices are those shown in the Column Info dialog box; also see Table 3.4 “Date/time formats supported in JMP,” p. 82. In Format(string, "format") Parses a string of a given format and returns date/time value expressed as if Parse Date(string, "format") surrounded by As Date(), returning the date in ddMonyyyy format. As Date(expression) Formats a number or expression so that it shows as a date when streamed out to a text window. 3 Operators 85

, ). 79 , Currency function. The TableVar , JSL Operators IsScriptable() RowState Column Format() , , .” To check whether a glo- .” To with the name of the item. with the Matrix , Picture , Name a number or missing numeric value, or 0 numeric value, number or missing a , Is Empty ? JSL has inquiry some- ? JSL has whether to test operators String DisplayBox obal variable, a data table, or a data column has a column data table, or a data a obal variable, , , an “uninitialized variable the format argument must be set to “Currency”. the format argument“Currency”. must to be set . List , time formats, see “Date/Time Operators,” p. time formats, see “Date/Time Number , s. To set a specific currency, use the the use currency, set a specific s. To Blob function that returns a string naming the type of the resultingnaminga string that returns function , or Unknown Type Integer . You can get errors if you try to refer to something that hasn’t been cre- can get errors if you try toto refer something that hasn’t . You , Date , Returns 1 if the evaluated1 argument if the is Returns otherwise. Explanation Is Empty Is is especially useful when partswhen is especially useful of a script depend on previous-generated results. Pattern Associative Array Associative , , . ) x Inquiryto identify object types functions Empty true , Type(1):"Integer" Type("hi"):"String" 2}):"List" Type({"a", "£12,345.600" Is Empty(myGlobal); Is Empty(dt); Is Empty(col); Is Type({"a",2})); Type("hi"), Show(Type(1), Format(12345.6, "Currency", "GBP", 3) "GBP", "Currency", Format(12345.6, Format(x,"format", <"currency code">, ) code">, <"currency Format(x,"format", Syntax Is Number( Table 3.6 Test that the previous results are scriptable and only continue with a script after a script continue with only scriptable and are results the previous that Test value assigned or not: results in results thing is or isn’t a specific type of data element. or isn’t thing is JSL also has an inquiry operator to test whether a gl a general JSL provides addition, In Table Expression Then argumentforspecific currency ISO add the is invalidas a quote string.code a 4217 third This example: For unless the format is set to “Currency”. can you tell whatkindofdataelement you have How JMP supports the symbol use of currency date (For number. a or is a column, x where a currency, as a column or number a designate To example, For ated or assigned a value yet. Programmers call this call valueaated or assigned yet. Programmers variable,bal datause table,has a value yet, or data column Is Scriptable() Is returns syntax is: value. The possible type names are are names value. The possible type Inquiry Functions Currency Chapter 3 86 JSL Operators Chapter 3 Functions that communicate with users

Table 3.6 Inquiry functions to identify object types (Continued) Syntax Explanation Is String(x) Returns 1 if the evaluated argument is a string, or 0 otherwise. Is Matrix(x) Returns 1 if the evaluated argument is a matrix, or 0 otherwise. Is Expr(x) Returns 1 if the evaluated argument is an expression, or 0 otherwise. Is Name(x) Returns 1 if the evaluated argument is a name-only expression, or 0 otherwise. Is List(x) Returns 1 if the evaluated argument is a list, or 0 otherwise. Is Associative Array(x) Returns 1 if the evaluated argument is an associative array, or 0 otherwise. Is Scriptable(x) Returns 1 if the evaluated argument is a scriptable object, or 0 otherwise. Is Empty(global) Returns 1 if the global variable, data table, or data column does not have a value Is Empty(dt) (is uninitialized), or 0 otherwise. Is Empty(col) Type(x) Returns a string naming the type of X.

Version and Host information Host Is is an inquiry operator. Host Is returns a boolean result, either 1 if true or 0 if false. This is useful for identifying the current operating system in scripts intended for use on Windows, Linux and Macintosh platforms. Although now not necessary, Host Is was frequently used to open data tables. For example: dt=if( host is(Windows), open("..\sample data\Big Class.JMP"), host is(Linux), open(“/usr/local/jmp/Sample Data/Big Class.jmp”), host is(Macintosh), open("::sample data:big class")); Another use is to specify different text sizes in reports for different operating systems. If you commonly write your scripts on Windows and share them with people who use them on Macintosh or Linux, the results can look different from what you intended. For example, this line sets the text to a larger size on Macintosh and a smaller size on Windows and Linux: txtsize = if(host is(Mac),12,10); The JMP Version() function returns the JMP version as a string. The function puts a leading blank on the version if it is less than 10 to make it easier to compare versions 7, 8, or 9 with version 10 in the future. This function is not available in releases prior to 6.0. JMP Version(); " 8.0"

Functions that communicate with users Show, Print, and Write put messages in the log window. Speak, Caption, Beep, and StatusMsg provide ways to say something to a viewer. Mail can send an email alert to a process operator. 3 Operators 87 34 in the “JSL JSL Operators except that it suppresses suppresses it that except except that it prints only only prints that it except Show Print Functions Functions that communicate with users are appropriate for the host environment. for the host environment. appropriate are isthe same as isthe same as 266 in the “Display Trees” chapter. Trees” “Display in the 266 Print Write escape sequences, see “Quoted Strings,” p. Strings,” see “Quoted sequences, escape the log. Notice that when you show variables, the resulting mes- the resulting variables, show you when that Notice log. the string, and it doesn’t start on a newincludeyou return line unlessa string, and it doesn’t , and its current value. value. current and its , : escape sequence. \!N insertscharactersthat the line breaking \!N sends the message you specify to the log. to the specify you the message sends sends the message you specify to the log. to the specify you the message sends Here is a message. Don’t forget to buy milk. milk. to buy forget Don’t a message. is Here bread. And Here is a message. is Here x:1 World" a:"Hello, "foo" 1 World" "Hello, "foo" causes the user’s computer to make an alert computer to sound. the user’s causes displays the items you specify in the items you displays myText="Here is a message."; a message."; is myText="Here to concatenate || // use buy milk."); to forget Don't write(myText||" return for \!N // use bread."); write("\!NAnd write("Here is a message."); is write("Here X=1;A="Hello, World"; X=1;A="Hello, show(X,A,"foo"); World"; X=1;A="Hello, print(X,A,"foo"); the quotation marks around the text the around quotation marks the with the character yourself the valueof each variable the withoutthe variablecolon. name and sage is the variable name, a colon aname,sage is the variable Beep Beep The sequence The Write Write Print Print Show Show JMP’s scripting language has methods for constructing dialog boxes to ask for data column choices and choices column to ask for data methods for constructing dialog boxes has scripting language JMP’s p. Dialogs,” other types “Modal of information. See For an explanation of the three line breaking line of three the an explanation For . chapter Blocks” Building Send information to the user Writing to the log Writing Chapter 3 88 JSL Operators Chapter 3 Functions that communicate with users

Speak Speak reads text aloud. On Macintosh, Speak has one boolean option, Wait, to specify whether JMP should wait for speaking to finish before proceeding with the next step. The default is not to wait, and you need to issue Wait(1) each time. For example, here’s a script certain to drive anybody crazy. With Wait(1), you’ll probably want to interrupt execution before long. If you change it to Wait(0), the iterations proceed faster than the speaking possibly can and the result sounds strange. On Windows, you can use a Wait(n) command to accomplish the same effect. for(i=99,i>0,i--, speak(wait(1),char(i)||" bottles of beer on the wall, " ||char(i)||" bottles of beer; " ||"if one of those bottles should happen to fall, " ||char(i-1)||" bottles of beer on the wall. ") A more practical example has JMP announce the time every sixty seconds: // Time Announcer script = expr( tod = mod(today(),indays(1)); hr = floor(tod/inHours(1)); min = floor(mod(tod,inHours(1))/60); timeText = "time, " || char(hr) || " " || char(min); text = Long Date(today()) || ", " ||timeText; speak(text); show(text); schedule(60,script); // seconds before next script ); script; You might use a similar technique to have JMP alert an operator that a process has gone out of control.

Note: For Speak to work on a Linux machine, the text-to-speech synthesizer program Festival must be installed and in the user’s path. If Festival is not found, the an error is reported to the lost that it was unable to find the speech synthesizer program.

Caption Caption brings up a small window with a message to the viewer. Captions are a way to annotate dem- onstrations without adding superfluous objects to results windows. The first argument is an optional {x,y} screen location given in pixels from the upper left; the second argument is the text for the win- dow. If the location argument is omitted, windows appear in the upper left corner. The Spoken option causes captions to be read aloud by the operating system’s speech system (if avail- able). Spoken takes a boolean argument, and the current setting (on or off) remains in effect until switched by another Caption statement that includes a Spoken setting. You can include pauses in the playback by including the named argument Delayed and a time in sec- onds. Such a setting causes that caption and all subsequent caption windows to be delayed by that num- ber of seconds, until a different Delay setting is issued in a Caption statement. Use Delay(0) to stop delaying altogether. This script turns speaking on and leaves it on until the last caption. 3 Operators 89 JSL Operators . Remove Functions Functions that communicate with users pt in a control chartpt in a control to trigger an email warning after its existence on the disk is verified. For For is verified. disk on the existence after its there is only one caption window available at a time. To is only one there caption availablewindow at time.a To i.e. data table, submit a new one, use the named argument Big Class.jmp about a condition in JMP. For example, a For a condition in JMP. user about to alerta email message an sends hides the previous one, hides the previous Mail Caption other attributes"); other bigClass=open("$SAMPLE_DATA/Big Class.JMP"); bigClass=open("$SAMPLE_DATA/Big class data.", "C:\myJMPData\Big Class.jmp"); "C:\myJMPData\Big data.", class at "||Format(today(), "d/m/y h:m:s")); "d/m/y "||Format(today(), at can also send an attachment with the email. An optional fourthanwith the can attachmentargument also send specifies the attach- caption("A JMP Data Table consists of rows and columns of data"); of data"); and columns rows of consists Table Data JMP caption("A named"); are columns and the numbered are rows caption("The right"); on the grid in the is itself data caption({250,50},"The and columns shows side left the along panel caption({5,30},spoken(0),"A caption({10,30},"A tour of the JMP Analyses", spoken(1), Delayed(5)); spoken(1), JMP Analyses", the of tour caption({10,30},"A Table"); a data caption("Open mail("[email protected]", "Interesting Data Set", "Have a look at this this look at a "Have Set", Data "Interesting mail("[email protected]", caption(remove); StatusMsg("string") control of 12A out "Process of control", "out mail("[email protected]", close a caption without displaying without displaying a caption close Mail only) (Windows Each new StatusMsg bar. status message to the a commandThis sends process control manager might include a testcontrol manager process might include a alert scri pager: her to Mail example, to attach the ment. The attachment is transferred in binary in format transferred is attachment ment. The Chapter 3

Chapter 4 Programming Functions Script Control

Sometimes you may need to program repetitive operations, or perhaps implement some statistical test that JMP doesn’t have built in. Then you will need to learn some of the functions that control flow. The following functions take on the roles that in other programming languages have statements with special syntactic structure. They are just functions in JSL, like any other functions, with arguments sep- arated by commas. This chapter covers basic programming functions and variables. The chapter “Advanced Concepts,” p. 401, covers more advanced techniques, such as throwing and catching exceptions and working with expressions. Contents Programming Example...... 93 Gluing expressions together ...... 93 Glue ...... 93 First...... 94 Example ...... 94 Iterating ...... 94 For ...... 94 While ...... 96 Summation ...... 96 Product ...... 96 Break and Continue ...... 96 Conditional functions ...... 97 If ...... 97 Match ...... 98 Choose ...... 98 Interpolate...... 99 Step ...... 100 Controlling script execution...... 100 Wait ...... 101 Schedule ...... 101 Variables...... 101 Global Variables ...... 101 Local variables ...... 102 JSL Data Structures ...... 103 Lists...... 103 Matrices ...... 107 Associative Arrays ...... 107 4 Programming Functions 93 , since there there , since n , the remaining n2 Programming ExampleProgramming Programming Functions Programming . It is useful to get in the habit . It of } is the significance level of the test. of level the significance is or ) function obtains the mean and count for function obtains the mean and count for p Value e test statisticthe hypothesis that under succession, returning the result of the last one. last of the result the returning succession, t terminator character. In JSL it is just a binaryJSL it In t terminator character. atistical method,atisticalthe of a type of runs test. Many returned is the result of the right-most expression. expression. right-most of the result is the returned ession as a terminator character, but it is not is but it terminator character, ession as a ing and pasting small scripts into larger ones. larger ones. scripts into small and pasting ing Summarize , two statements which makes the the same: following Glue , the number of heights greater than the mean; than the mean; greater of heights , the number n1 ready familiar from the “JSL Operators” chapter. func-A flow-control familiar “JSL ready from the Operators” g parenthesis or closing g parenthesis brace: is the normalis test statistic,and gets the number of rows, which will be the same as the count same as the the will be which number of rows, the gets zTest NRow , is also used to iterate computations over many rows at a time. at rows many over computations to iterate used also is , are the mean and standard deviation of th of deviation standard the mean and are , the number of adjacent heights that are not both above or both below the mean. The mean. the or both below not both above adjacent heightsof that are number , the r sigmaR Summation and Glue(a=2,b=3) b=3 a=2; i=0; j=2 i=0; Open("$SAMPLE_DATA/Big Class.jmp"); Open("$SAMPLE_DATA/Big Summarize(mean=mean(Height),n=count(Height)); = nrow(); nr nr, Height[i]>mean); = summation(i=1, n1 = n-n1; n2 (Height[i]>mean)!=(Height[i-1]>mean)); nr, = summation(i=2, r = 2*n1*n2/(n1+n2); muR sqrt(2*n1*n2*(2*n1*n2-n1-n2)/(n^2*(n-1))); = sigmaR (r-muR)/sigmaR; = zTest distribution(abs(zTest)))*2; (1-normal = pValue p Value); zTest, muR, sigmaR, show(r, lues would be more likely to be alikebewhether in likely to more time, then neighboring values would be patterna across is there If mean. the or below above were they there is no run pattern, there using a final semicolon to avoid errors whenerrors copy using a final semicolonto avoid the column height. required. The semicolon is ignored if nothing follows it. Trailing semicolons are allowed at the end of a allowed are semicolons it. Trailing follows nothing if is ignored The semicolon required. a closin and before stream, script For example: For canat also add a semicolon the end expr of an You The semicolon operator just evaluates each argument in argument each evaluates just operator semicolon The The semicolon in otherlanguagesstatemena is used as operator for gluing together expressions. The result result The expressions. operator for gluing together is semicolon of the function version The The first statement opens a JMP data table. The Here is an example script using JSL to implement a st implement to example script using JSL is an Here al used in this script are functions tion, are no missing values. no missingThen values. it are finds number; and muR Gluing expressions together Gluing expressions Glue Programming Example Programming Chapter 4 94 Programming Functions Chapter 4 Iterating

First The First function works just like Glue ( ; ) except that it returns the first argument’s result instead of the last’s. For example, this script increments a counter global i after getting the ith value of a variable, but enclosing the two steps inside First( ) enables the script to return the datum, not the new value of the counter. i=1; First(height[i], i++);

Example What are the results of this script? a=root(b=9;4); Semicolon has weak precedence, so when JMP evaluates this statement, it first attempts to evaluate the quantity inside the parentheses. JMP simply executes two separate statements: b=9; 4; Thus it assigns 9 to b, then it evaluates the last statement, 4. Several statements glued together return the return value of the last statement, so 4 is returned for the expression inside the parentheses. JMP then takes the square root of 4 and assigns the result (2) to a. Assignment always returns the assigned value, so the ultimate return value for the whole script is 2. So, this script results in two assignments, a=2 and b=9, and returns 2. What are the results of this script? a=root(First(b=9,4)); First executes both its statements but returns the result of the first, not the last. So the statement 4 accomplishes nothing, 9 is assigned to b, and the square root of 9, 3, is assigned to a.

Iterating JSL provides For, While, Summation, and Product to iterate actions according to the conditions you specify. To iterate actions over rows of a data table, use For Each Row, which is discussed in the “Data Tables” chapter.

For The For function first evaluates init expression, but just one time. Then it tests the while expression, breaking if not true. As long as the while expression is true, it keeps executing the body and iter expres- sions. For(init, while, iter, body); 4 Programming Functions 95 test. If . to 2, evalu- . Only one (adds one to (adds i i Iterating i -period on Mac- s+i a ). The first three first three ). The , with the punctuation is dif- is the punctuation s butthe variable the and Programming Functions Programming (if there’s more waiting after the waiting after more (if there’s to 3, evaluates 3<3false, and as i typically it increments typically it increments is always a condition, like a little ). Semicolons let numerous things let numerous stand in ). Semicolons ; condition like this one, condition like this stribution platform for the first column, incre- of the fourthis done, the counter argument vari- at the second argument, at the testing again whether , is true. If it is true, then it does the action script. comes next inside the for’s parentheses. You’ll You’ll parentheses. the for’s comes next inside e loop, and the fourth is what to do repeatedly— fourth what to do the is and e loop, is a function where commas separate argu- commas separate function where a is is a special clause where semicolons sepa- where a special clause is to infinite loops. When this happens, you can use the ogramming language, although ogramming language, For for i<=20 this case, it assignsthe value this case,a variable it 1 to the for loop. In this case, it replaces replaces this case, it In the for loop. completing the completing actions; e loop (press Escape on Windows, or type on Windows, Escape e loop (press after continues with the rest of the of the script the rest with continues If you know C, watch out for the difference between JSL and C in the JSL and between difference the for out C, watch you know If -Period on Macintosh to stop the Macintosh looping.) on -Period of the for loop). The second argument second of the for loop). The a ) to 0, evaluates to 0, 0<3astrue, launches the Di is still true. i loop works like expects this. fourIt arguments separated with commas ( is incremented, and the execution starts over execution and the incremented, is rate arguments and commas join them. them. join commas rate arguments and use of semicolons and commas. In JSL JSL use semicolons and commas. In of Confusion alert! alert! Confusion ments and semicolons join them; in C semicolons and ments i to 1, evaluates 1<3 as true, does Distribution for the second column, increments increments column, for the second Distribution true,does as 1<3 evaluates to 1, For justloops like it does in the C (and C++) pr initialized in the first argument, but that’s not initialized the same variable in the first argument, involves but the condition that’s Usually Esc press can you make a mistake, (If you loop. infinite an not to create Be careful case. always the or on Windows value). The its current everythingactions are that step 5. in come backto this last parenthesis If false, it ends the for loop and the for false, it ends If i<=20 s=0; For(i=0, i<=20, i++, s=s+i); s=s+i); i++, i<=20, For(i=0, s=0; for(i=0, i<3, i++, Distribution(column(i+1))); i<3, for(i=0, able place of one thing. The first argument of a for loop is always a starting argument of a for loop is first The valueanything. could be command statement is expected in the commandis expected fourth statement argument. you If want to do several things on each ( with semicolons together the statements glue step, ferent. 3 argument is what to do The third 4of work does the fourth argument The The The For example, you can do a Distribution on the first three columns of the current data table: current of the columns the first three on do a Distribution can you example, For sets This For ments i intosh). 20: 0 to from numbers sums the expression following The 5 argument in. kicks the third After the action Now arguments are rules for how many times to repeat th repeat times to many how for rules are arguments this is where the action takes place. where is this 1In an initial condition or state. it sets First 2 it tests whether the second argument, Next ates 2<3 as true, does Distribution for the third column, increments increments column, for the third Distribution as true,does ates 2<3 finally outthe breaks loop. of that to write scripts get in is not hard course, it Of keyboard cancel sequence to get out of th cancel sequence keyboard Chapter 4 96 Programming Functions Chapter 4 Iterating

While A related function is While, which repeatedly tests the condition and executes its body script as long as the condition is true. While(condition, body); For example, here are two different programs to find the least power of 2 that is greater than or equal to x: x=287; y=1; while(y

Summation The Summation function adds up the body results over all i values. For example: s = Summation(i=0,10,i); // which is 0+1+2+....+9+10 This is the same idea as Σ in the calculator except that with Summation you needn’t restrict yourself to creating formula variables. Summation(i=1, NRow(), x^2); This is the JSL equivalent in the formula calculator: NRow x2 ∑i = 1

Product The Product function works just like Summation, except that it multiplies the body results rather than adding them. p = Product(i=1,5,i); // which is 1*2*3*4*5 This is the JSL equivalent of this in the formula calculator: 5 ∏ i i = 1

Break and Continue Two functions give you further control over looping: Break() and Continue(). These two functions work with For and While loops, and also with For Each Row.

Break Break immediately stops the loop and proceeds to the next command after the loop. This is usually used inside a conditional statement. For example: For( i = 1, i <= 10, i++, If( i == 5, Break() ); Print( "i=" || Char( i ) ); ); 4 Programming Functions 97 ). is also , and from 1 to 10, 1 to from i Continue Interpolate printed to the log printed to the , i Conditional functions Conditional Show(“Finished”) Programming Functions Programming Choose , atement is not executed. There is There atement is not executed. body has already been executed, so been executed, already body has the loop completely. the loop completely. Match , If e whennext thatresult condition evaluates as ways return despite missing conditionals is to add conditionals despite missing return ways en condition evaluates as true evaluatescondition en as (nonzero and preceding conditions are true—it is the “else” result. the “else” true—it is are conditions preceding , the loop wouldloop print, the outthe values of reaches 5, the loop is immediately halted (before the immediately halted (before the loop is 5, reaches i Break is greater than 5, the print is greater st i . It immediately stops the current iteration of the loop, but sends but iteration sends of the loop, stops the current immediately . It to missing, the function keeps on evaluating and only returns missing and only returns evaluating keeps on the function to missing, clause) if none of the clauses evaluated to true and at least one condi- clauses clause)true evaluatedleastone at if none of the to and at the end of a loop: the entire loop the entire loop: at the end of a Break the loop will continue anyway. , but until else is 5) and the following statement is processed ( processed statement is is 5) and the following i i . However, as soon as as . However, Continue statements were at the end of the loop, the final value of final value the loop, end of the at the were statements statement that contains Break If gentler is a form of “Finished” and function returns the result statement(s) wh the result function returns If( i < 5, Continue() ); 5, Continue() i < If( ); i ) Char( || "i=" Print( If . If If (age<12,"Young", a>12,"Old", 1,"Ageless"); 1,"Ageless"); a>12,"Old", (age<12,"Young", If X = If(Y<20,Y,20); If (Age<12,"Child",Age<18,"Teen","Adult"); = Age Group row()=1; ); ) resultLast ...., result2, condition2, result1, ( condition1, If For( i = 1, i <= 10, i++, <= 10, 1, i i = For( Show( "Finished!" ); "Finished!" Show( would be 5 rather than 4. Continue tional returned missing. The way to get a missing. tional clause returned to al a conditional at the end that is always true. For example, a conditionalis always true.thatend at the For there is nothing to skip, and nothing to skip, is there and then print statement, butafter usually used inside a conditional statement. For example: statement. For a conditional inside used usually no point to placing a execution back to the beginning of the loop rather than stoppingrather than the loop back to the beginning of execution (rather than evaluatingthe 20. less than 20; otherwise,to Y is sets X X to Y if it code sets the following example, For for example: ranges, recode this to can use You If at least one If condition evaluates Step The JSL provides five functions to execute script conditionally: script conditionally: execute functions to five provides JSL This loop iterates through loop iterates through This Continue Without the Without If the non-missing). Otherwise it skips ahead and returns th Otherwiseit skips ahead and returns non-missing). theif noneof true.final is the result The result If Conditional functions Chapter 4 98 Programming Functions Chapter 4 Conditional functions

You can put actions and assignments in the result clauses, and you don’t have to return a result. For example the following two are equivalent: X = If(y<20,y,20); If(y<20,x=y,x=20); Similar conditionals are Choose and Match. Be careful to use == for equality tests, not =. An If with an argument like name=value would assign the value rather than test it.

Match The Match function allows you to make a sequence of equality comparisons without needing to rewrite the value to be compared. The result of the first operand is compared to each of the succeeding even operands, except the last, and if they are equal, the value of the operand immediately after is returned. If nothing matches, then the last operand is returned. For example: SLabel = Match(SCode, 1,"Male", 2,"Female", "unknown"); This would be equivalent to the following If expression: SLabel = If(SCode==1,"Male", SCode==2,"Female", "unknown"); With more groups, the value of Match becomes more apparent: dt=open("$SAMPLE_DATA/Big Class.JMP"); for each row(ageword= match(age, 12, "twelve", 13, "thirteen", 14, "fourteen", 15, "fifteen", 16, "sixteen", "seventeen"); show(age, ageword)); If a has integer values 1, 2, 3, ..., you can save even more typing by using Choose.

Confusion alert! If and Match now handle missing values differently than in JMP ver- sion 3.x (as do And and Or ). Previously missing values returned false (the “else” result for Match); now they return missing values, as discussed under “Missing values,” p. 77 in the “JSL Operators” chapter. For the v. 3 behavior, you can use IfMZ and MatchMZ (and AndMZ and OrMZ). These -MZ operators are used automatically when converting formulas from v. 3 data tables.

Choose The Choose function can be used to shorten certain recoding even more, provided the arguments are to be tested against integers 1, 2, 3, etc. If the first argument evaluates to 1, Choose returns the first replacement value; if it is 2, the second, and so on. If the first argument evaluates to a integer out of 4 Programming Functions 99 Conditional functions Conditional -value between two points x Programming Functions Programming returns the last replacement value. For For value. replacement the last returns Choose nction by linear interpolation between integers, 0 between interpolation linear by nction -value corresponding to a given-valuea corresponding to which is what is being approximated. being what is which is y -values y and acement values are listed), listed), are values acement x- ied as a list of points a ied as ). , y2 linearly interpolates the x2 ), and ( 54.59815003314424 148.4131591025766] 54.59815003314424 , y1 xgrid:[0 1 2 3 4 5] 1 2 3 xgrid:[0 20.08553692318767 7.38905609893065 2.718281828459045 yvalues:[1 Interpolate(x, x1, y1, x2, y2, ...) y2, x2, x1, y1, Interpolate(x, ymat) xmat, Interpolate(x, (0::5); = xgrid = yvalues exp(xgrid); yvalues); show(xgrid, SLabel = Choose(SCode,"Male","Female","Unknown"); = SLabel "high"); group==3, "medium", group==2, "low", if(group==1, 3, "high"); 2, "medium", 1, "low", g2=match(group, "high"); "medium", "low", g3=choose(group, x1 to 5. The following would create the two vectors of values: the two would create following to 5. The with compared line), like (dashed what the interpolationfunction would look of a plot is Following (solid line), version continuous what the Suppose we wanted to approximate the exponential fu exponential the we wanted to approximate Suppose output produces the This or as matrices containing the Interpolate range (e.g. 7 when only 5 repl range (e.g. 7 when only column is a same with values2, task, all accomplish and the 1, replacing the 3, following Thus, if group with “high.” and 3s “medium,” 2s with 1s with “low,” example: ( The specif can be points The Interpolate Chapter 4 100 Programming Functions Chapter 4 Controlling script execution

Figure 4.1 Interpolate Exp()

The points must be arranged in ascending order. For example, Interpolate(2,1,1,3,3) returns 2. However, Interpolate(2,3,3,1,1) returns a missing value (.).

Step Step is like Interpolate except that it finds the corresponding y for a given x from a step-function fit rather than a linear fit between points. That is, it returns the y-value corresponding to the greatest x-value that is less than or equal to the x specified as the first argument. Step(x, x1, y1, x2, y2, ...) For example: for(i=1,i<7,i++,print(step(i, 1,10, 3,30, 4.5,45, 7,70))); 10 10 30 30 45 45 As with Interpolate, the points must be in ascending order.

Controlling script execution When you run a script, the Run Script command in the Edit menu changes to Stop Script. While a script is executing, you can select this item (or type Esc on Windows or a-Period on Macintosh) to stop it. Many scripts execute more quickly than you can stop them. 4 Programming Functions

101 to All Watch Variables command allows command allows This approach is some- is approach This Wait Programming Functions Programming —allows JMP to other pending —allows do ble space that all scripts use. You can also create ble space that all scripts use. You Wait(0) updates whenever values change while the script is values updates whenever pausing the specified number of seconds before specified number before of seconds pausing the ntinue runningscript. the can be runwaiting. while This includes updating self by insimply editing the value the shown these events. Waiting zero seconds is useful for allow- is useful for seconds zero Waiting events. these r interactive use use or r interactive demonstrations. ample, this is a 15-second timer: Issuing a wait time of 0— Issuing runs commands or entire scripts at the times you specify. See the “Production Environ- the “Production See specify. you times scripts at the runs commands or entire lets you keep track of the value in a global variable. to report draws a the values window the namedof global argument variables you list. Use allows you to slow down scripting playback by scripting down slow to you allows tasks system so that system, the to also yields Watch(a, b); Watch(a, Watch(all); x=2; Wait(15); Wait the contents the contents of the screen. continuing with the script. For ex For the script. with continuing events, but not wait any longer than needed to do longer than but not wait any events, to the yielding before end to the script for away; otherwise right waits be displayed JMP to ing results systemto update windows. you to pause script execution for a time and then co for a time execution pause script to you times necessary fo times intended scripts for watch the values for all global variables. The window or youexecuting, can manually change values your window. This is a useful debuggingis a usefultool. This window. Following are a fewa commands that can help you manage are global variables. Following Watch Watch Watch makes a global variable.has JMP a single global varia local variables. Assigning a variable this way: Schedule Stopping a scriptStopping manually contrast,In stops the the entire script completely. Wait ments” chapter. ments” Global Variables Variables Schedule Wait Chapter 4 102 Programming Functions Chapter 4 Variables

Show Globals and Clear Globals Show Globals lists all global variables defined, along with their current values. Clear Globals erases the values set for all global variables defined.

Note: This is not the same as erasing the global variables themselves. The only way to erase a global variable completely is by quitting JMP.

show globals(); //Globals a = "Hello, World"; b = 0; dt = DataTable("Big Class"); myRoot = Function({x},If(x>0,Sqrt(x),0)); x = 1; // 5 Globals clear globals(); show globals(); //Globals a = empty(); b = empty(); dt = empty(); myRoot = empty(); x = empty(); // 5 Globals

Locking and Unlocking Global Variables If you want to lock a global symbol to prevent it from being changed, use Lock Globals. Lock Globals (name1, name2, ...) To release the lock and enable the global to be changed, use Unlock Globals. Unlock Globals (name1, name2, ...) The primary use of these two commands is to prevent scripts from interfering with each other. For example, locking prevents a Clear Globals() command from inadvertently clearing a global that is being used by another script. Another way of preventing two or more scripts from clobbering each other’s variables is to use local variables.

Local variables Local lets you deal with local variables without affecting the name space around you. For example, suppose you want to call something x, but there could already be an x global in another script that is calling your script. Just put x inside a Local block. y= Local({x}, x = sqrt(b^2-4*a*c); {(-b+x)/(2*a), (-b-x)/(2*a)}); The general form is: Local( {list_of_variables_or_assignments}, body ); 4 Programming Functions

103 Local . . Remember, . Remember, Eval List Eval JSL Data Structures JSL with arguments. The short- The arguments. with Programming Functions Programming s. {a(1), b(2)} {a(1), List Local are never seen never outside the scope of the are lly items of different type: numbers, text strings, lly items of different py of itself. It does not evaluate items inside the inside items does not evaluate It py of itself. s and other s and other y without changing the permanenty withoutchanging contents of the and mx —, or function calls— mn contains the variable B, not its current value: current the variable B, not its contains veralother datatypes variables can hold: Function if you want to evaluate the contents, use lists. lists. A list is just the function expression that match that names listed expression for argument first are the {a=1, b=2} {a=1, body s can be nested ins can be nested if you want a list with all its items evaluated:youwant if a listwith all its Local is to use curly braces. Thus the following two statements are equivalent: are two statements following Thus the to use curly braces. is List A:{1,2,B,Sqrt(3)} 1.732050807568877} 2, 7, {1, polynomial:a*x^2+b*x+c polynomial:a*x^2+b*x+c show(polynomial)); show(polynomial)); polynomial:d*x^3+a*x^2+b*x+c polynomial:a*x^2+b*x+c Eval List B=7;show(A); List(A); = Eval C show(polynomial); show(polynomial); A = List(1,2,B,sqrt(3)); A = {1,2,B,sqrt(3)}; local({polynomial=insert(expr(a*x^2 + b*x + c), expr(d*x^3),1)}, c), expr(d*x^3),1)}, b*x + + local({polynomial=insert(expr(a*x^2 y = local( {mn=min(x,y),mx=max(x,y)}, mx*(mx-1)+mn ); mx*(mx-1)+mn {mn=min(x,y),mx=max(x,y)}, local( = y + c); + b*x polynomial=expr(a*x^2 show(polynomial); hand for function: Use assignments— hold also can Lists When youdefineevaluateor a list, it just returns a co •Lists •Matrices • Arrays Associative containersLists numerousare to store items—potentia other even and matrices, expressions, this instance, step that the list reveals list. For Besides numbers and strings, JSL provides se JSL and strings, provides numbers Besides All occurrences of names in the the in names of All occurrences locally. resolved temporaril expression manipulates an example This expression: expression: Another example: in the following expression, expression, the following in Another example: statements such as these just return lists; statements such as these just return Lists JSL Data Structures Chapter 4 104 Programming Functions Chapter 4 JSL Data Structures

assignList={a=1, b=3, c=5}; {a=1, b=3, c=5} show(assignList); assignList:{a = 1, b = 3, c = 5} evallist(assignList); {1, 3, 5} show(a,b,c); a:1 b:3 c:5 show(assignList); assignList:{a = 1, b = 3, c = 5}

h=function({x},x+2); i=function({x},x+3); k=function({x},x+4); fnList={h(1), i(3), k(5)}; fnlist:{h(1), i(3), k(5)} show(fnList); fnList:{h(1), i(3), k(5)} evallist(fnList); {3, 6, 9} show(h,i,k); h:Function({x},x + 2) i:Function({x},x + 3) k:Function({x},x + 4) show(fnList); fnList:{h(1), i(3), k(5)}

Assignment List assignment is powerful. {a,b,c} = {1,2,3}; //assigns 1 to a, 2 to b, 3 to c {a,b,c}+=10; //adds 10 to each variable a, b, and c. {{a},{b,c}}++; //increments a, b, and c by 1 {a,b,c}--; //decrements a, b, and c mylist={1, log(2), e()^pi(), height[40]}; // stores the expressions in a list Note that any structure of a list is supported, as long as the arguments are conformable and ultimately numeric. One-element lists are treated like scalars for conformability. For example, a = {{{{{1, 2}, {3, 4}}, {5, {6, 7}}}, 8}, {9, 10}}; b = {{{{{10, 20}, {30, 40}}, {50, {60, 70}}}, 80}, {90, 100}}; c = a + b; show(c); d = a + 100; show(d); e = sqrt(a); show(e); results in the output c:{{{{{11, 22}, {33, 44}}, {55, {66, 77}}}, 88}, {99, 110}} d:{{{{{101, 102}, {103, 104}}, {105, {106, 107}}}, 108}, {109, 110}} e:{{{{{1, 1.414213562373095}, {1.732050807568877, 2}}, {2.23606797749979, {2.449489742783178, 2.645751311064591}}}, 2.82842712474619}, {3, 3.16227766016838}} 4 Programming Functions

105 . a[i] and value must be a num- i , where , where must be a list but JSL Data Structures JSL a value Programming Functions Programming Contains(list, value)>0 Contains(list, contains a list of things that are sub-contains a list of things that are a function: that are equal to that are where where e.g. list NItems use otherwise try JMP would use it and to evaluate is equivalent to is equivalent list is [1],[0] notsome other languages. as in s, you can use a quoted name for the subscript: subscript: for the quoted name a can use s, you be a number. So, in the above example, the above in So, be a number. is not found, the resulting matrix has zero rows and zero col- ied item(s) from a list. Subscripts can in turn be lists. Note that JSL that Note can in turn be lists. Subscripts a list. from ied item(s) value function. a[i][j] = a[i][j] value

Loc e.g. NRow(Loc(list, value))>0 NRow(Loc(list, could be a matrix or list of indices. or list of be a matrix could j X[a]:b(3) XX[a]:b=3 X["a"]:1 XX["a"]:1 can be strings or numbers. If can be anything subscriptable. a[i][j][k][l][m][n] = 99; a[i][j][k][l][m][n] value) Loc(list, a=2;show(X[a],XX[a]); c={1,2,3}; {4,4,3} c to // changes c[{1,2}]={4,4}; // equivalent c[{1,2}]=4; c(5)}; b(3), X={a(1), c=5}; b=3, XX={a=1, XX["a"]); show(X["a"], N = N Items(A); = N {x,y,z}}; 4, [1,2,3], a={"bob", "bob" // returns show(a[1]); {"bob",[1,2,3]} // returns show(a[{1,3}]); 4 to 5 the // changes a[2]=5; ber, but ber, scriptable) are allowed in certainallowed scriptable) cases. are 1 example, the above in the outermost must be a list. So, except level Each Locating items in a list find values in a list, use the To the in values to the indices of a matrix returns This list its value, like this: its value, left-side subscripts ( Multiple You need to put the name in quotation marks, beca name in quotation marks, need to put the You You can also use subscripts to select or changeitems in a list.or to select subscripts can use also You or function list assignment lists have you When How many items? the list, use a in the number of items determine To Subscripts the specif for lists extract Subscripts in a the first element 1, so startscounting from 2 Each subscript the outermost must except The subscripting can be done to any level of nesting.anyThe subscripting level of can be done to umns. Therefore, Therefore, umns. Chapter 4 106 Programming Functions Chapter 4 JSL Data Structures

Note: Complete details on matrix manipulation are found in the “Matrices” chapter, including the description of the equivalent Loc command for matrices (which requires only one argument). For example, given these lists: nameList = {“Katie”, “Louise”, “Jane”, “Jane”}; numList = {2, 4, 6, 8, 8} Loc(nameList, “Katie”) returns [1] Loc(nameList, “Erin”) returns [], an empty matrix, since there are no matches. Loc(nameList, “Jane”) returns [3, 4] Loc(nameList, 1) returns []. Note that the type mismatch is tolerated. Loc(numList, 1) returns [] Loc(numList, 6) returns [3] Loc(numList, 8) returns [4, 5] Here’s a summary of the list operators:

Table 4.1 Operators for working with lists Operator Syntax Explanation {} List List(a, b, c) Constructs a list from a set of items. An item can be any expres- {a, b, c} sion, including other lists. Items must be separated by commas. Text strings should either be enclosed in double quotation marks ( "") or stored in a variable and called as that variable. N Items N Items(list) Returns the number of elements in the list specified. Can be assigned to a variable. Is List Is List(arg) Returns true (1) if arg is a classical list, i.e. one that would result from the construction by List(items) or {items}, and returns false (0) otherwise. An empty list is still a list, so IsList({ }) returns true. If miss=., then IsList(miss) returns false, not missing. [] Subscript list[i] Subscripts for lists extract the ith item from the list. Subscripts x = list[i] can in turn be lists or matrices. list[i] = value a[b,c] Subscript(a,b,c) = Assign {list} = {list} If the target of an assignment operator is a list and the value to += Add To {list} –= value be assigned is a list, then it will assign item by item. The ulti- -= SubtractTo {list} += {list} mate values in the left list must be L-values, i.e. names capable *= MultiplyTo ... of being assigned values. /= DivideTo Note: If you want to test equality of lists, use ==, not =. ++ Post Increment -- Post Decrement Eval List Eval List(list) Returns a list of the evaluated expressions inside list; see “Lists,” p. 103. 4 Programming Functions 107 JSL Data Structures JSL message, a default value does. If a default value has a default value If does. Programming Functions Programming is not in the map. Initially, maps have have maps Initially, map. is not in the list[-1] key Set Default Value Set Default ed in lexicographical order for the purpose of iter- purpose for the order lexicographical ed in when without a key. For example: For key. a without table as well as matrix algebra. the See “Matrices” values, which may not be unique. Though associative the following: the ems can be added and changed with subscripting: with and changed added be can ems map[key] =>value will cause an error muchwill cause an error like array, use one of array, ll be returned. Besides the Besides be returned. ll map[key] determines the value of determines the value values value 2-item lists 2-item map = Associative Array({"yes", "no"}, {0, 1}, 2); // with default value with default // 1}, 2); {0, "no"}, Array({"yes", = Associative map refs column two // :height); Array(:name, = Associative map value default with // .); :height, Array(:name, = Associative map map = Associative Array({"yes", "no"}, {0, 1}); // two lists, keys and keys lists, // two 1}); {0, "no"}, Array({"yes", = Associative map map = Associative Array({{"yes", 0}, {"no", 1}}, 2); // with default default with 2); // 1}}, {"no", 0}, Array({{"yes", = Associative map counts = ["a"=>10, "b"=>3, =>0]; // default value of 0 value // default =>0]; "b"=>3, ["a"=>10, = counts 0] 1, => "c" => => 3, "b" 10, => ["a" 1; // += counts["c"] array associative empty // = [=>]; map value default with // = [=>0]; map array associative // literal 1]; => 0, "no" => = ["yes" map value default with // 2]; 1, => => 0, "no" => = ["yes" map array associative empty // Array(); = Associative map value default with // Array(0); = Associative map containing list // 1}}); {"no", 0}, Array({{"yes", = Associative map cary = [=>]; cary Array(); = Associative cary = "NC"; cary["state"] 116234; = cary["population"] = "cloudy"; cary["weather"] 10; += cary["population"] = "sunny"; cary["weather"] Creek"}; "Panther Hope", "Green = {"Cary", schools"] cary["high no default value and and value no default can be set in the literal constructorthe literal in can using be set been set, then that value wi Associative Array Constructors Associative Note that L-valuesan injustlikeany associative L-value. other array are Note default value The ation and serialization.ation and associative an empty create To The keys andIt valuesJSL objects. anybe can An associative array associates unique keys with Matrices can be used to represent values in a data values can be used to represent Matrices chapterdetails. for return JMP keys are generally not ordered, arrays are Matrices Arrays Associative Chapter 4 108 Programming Functions Chapter 4 JSL Data Structures

set = Associative Array({"yes", "no"}); // one list creates a set with default value 0 set = Associative Array(:name); // one column ref creates a set with default value 0

Working with associative arrays To determine the number of keys that an associative array contains, use N Items. Using the cary asso- ciative array from earlier: N Items(cary); 4 There are several functions that can be used for associative arrays in addition to lists, strings, and expressions. Adding and deleting keys and values Insert, Insert Into, Remove, Remove From, Reverse, and Reverse Into can all be used to add key-value pairs or remove them from the associatice array entirely. Insert and Remove return copies of the given associative array with the key-value pair added or removed. Insert Into and Remove From add or remove the key-value pairs directly from the given associative array. Insert and Insert Into take three arguments: the associative array, a key, and a value. newcary = Insert(cary, "time zone", "Eastern"); show(cary, newcary); cary:Associative Array({ {"high schools",{"Cary", "Green Hope", "Panther Creek"}}, {"population", 116244}, {"state", "NC"}, {"weather", "sunny"} }) newcary:Associative Array({ {"high schools", {"Cary", "Green Hope", "Panther Creek"}}, {"population", 116244}, {"state", "NC"}, {"time zone", "Eastern"}, {"weather", "sunny"} })

Insert Into(cary, "county", "Wake"); show(cary); cary:Associative Array({ {"county", "Wake"}, {"high schools", {"Cary", "Green Hope", "Panther Creek"}}, {"population", 116244}, {"state", "NC"}, {"weather", "sunny"} }) Remove and Remove From take two arguments: the associative array, and a key. newcary = Remove(cary, "high schools") show(cary, newcary); cary:Associative Array({ {"county", "Wake"}, 4 Programming Functions 109 JSL Data Structures JSL Programming Functions Programming ese two statements are equivalent. are two statements ese is returned. returned. is Empty() , which the returns value for a single key: out the associative array’s contents. array’s the associative out also have message equivalents. Th message equivalents. have also associative array’s contents associative array’s to determine if there is a default value set for an associative array, and if array, for an associative value is a default to determine set if there < "sunny"] "weather" 0 "state"} "population", schools", "high {"county", "NC"} 116244, Creek"}, "Panther Hope", "Green {"Cary", {"Wake", "Wake"} {"NC", 1 {"high schools", {"Cary", "Green Hope", "Panther Creek"}}, "Panther Hope", "Green {"Cary", schools", {"high 116244}, {"population", "NC"}, {"state", "sunny"} {"weather", }) => "NC", "state" 116244, => "population" "Wake", => newcary:["county" cary:Associative Array({ cary:Associative "Wake"}, {"county", Creek"}}, "Panther Hope", "Green {"Cary", schools", {"high 116244}, {"population", "NC"} {"state", }) <

cary <

Sets A set is an application of an associative array in which all the keys have a value of 1 and non-keys have an implicit value of 0. To facilitate set usage, 1 is the default value for inserted keys if no value is provided: map << insert("sample"); map["sample"]; 1 If you construct an associative array from a list, then the default value is set to 0 for you. Otherwise, you need to set the default value to 0 explicitly.

Graph Theory Associative arrays can be used for graph theory data structures, such as the following directed graph example: g = Associative Array(); g[1] = Associative Array({1, 2, 4}); g[2] = Associative Array({1, 3}); g[3] = Associative Array({4, 5}); g[4] = Associative Array({4, 5}); g[5] = Associative Array({1, 2}); The following depth-first search JSL function may be used to traverse this map, or any other directed graph expressed as a map: dfs = Function( {ref, node, visited}, Local( {chnode, tmp}, 4 Programming Functions 111 JSL Data Structures JSL nodes visited. To see how see how To nodes visited. Programming Functions Programming cond is the node you want to use as the startinguse as the you want to node cond is the contents ) || "\!N" ); "\!N" ) || contents dfs( g, 2, J( N Items( g << get keys ), 1, 0 ) ); ), 1, keys get << g N Items( 2, J( g, dfs( visited[node] = 1; = visited[node] = ref[node]; tmp first; << = tmp chnode ), chnode Missing( !Is While( !visited[chnode], If( ) visited chnode, ref, = Recurse( visited ); ); chnode next( tmp << = chnode ); visited ) ); Write( "Node: " || Char( node ) || ", " || Char( ref[node] << get << ref[node] || Char( ", " ) || node || Char( " "Node: Write( The first parameter is a reference to the map, the se the map, to the parameterThe first a reference is point, and the third is simply a vector that is simply a vector the function uses to keep track of point, and the third trythis function works following: the Chapter 4

Chapter 5 Data Tables Create, open, and manipulate data tables

JMP has many kinds of objects that can respond to messages. This chapter shows how to create and manage data objects: data tables, data columns, and rows. JSL’s messages for working with data corre- spond to the items in the Tables, Rows, and Cols menus in the graphical user interface, and in turn to items in the various panes of a data table window. This chapter starts with an introduction to data objects and how to send messages to them and contin- ues with the JSL for working with each of the objects. Contents Data table basics...... 115 Getting a data table object...... 115 Objects and messages ...... 118 Messages for data tables ...... 122 Naming, saving, and printing ...... 122 Journal and Layout ...... 123 Creating and deleting columns ...... 124 Accessing values...... 125 Summarize ...... 129 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 5 Scripting Data Tables 115 36 in Set Set Data Tables Data table basics ta tasks by sending messages to ta tasks by sending messages a to move up one folder level. Example scripts Exampleup one folder level. move to tion of the .JSL file (if the script has been saved) saved) has been script (if the .JSL file tion of the ble in memory, opening is equivalent to reading to reading opening is equivalent ble in memory, the table will not be the same as the one on disk same as the be will not the table with a data tablewill produce a data table object. six built-in path variables, see “File Paths,” p. six Paths,” built-in path variables, see “File ../ data table. This section examines how to open and to open section examines how This data table. in quotation marks or an expression yielding a path yielding or an expression marks in quotation en a data table object, you’ll step back and look at en a data table you’ll object, JMP does itnot read again but instead brings that e installed Scripts folder. We now also support also a now We folder. Scripts e installed is a path (either is a path or absolute)the data table. to relative ),... ) ),... you need to include some additional arguments.to include some you need Open . colWidth files from the installed Sample Data folderassumeandinstalled the Sample the script files from is ties, and interact with their data.with theirties, and interact ( presents a dialog prompting the user to navigate to a file. navigate the user to prompting a dialog presents open, you accomplish most other da most accomplish open, you Open colType command. command. is an integer specifying the width of the colummn the of the width specifying an integer is is Character|Numeric is colType colWidth // // // Number of Columns(number) of Number Columns(colName= Open("$SAMPLE_DATA/big class.jmp"); // just open the data table the data open just // class.jmp"); Open("$SAMPLE_DATA/big reference a assign and // open class.jmp"); dt=Open("$SAMPLE_DATA/big End Of Field (Tab|Space|Comma|Semicolon|Other|None) Of Field End ("char") EOFOther (CRLF|CR|LF|Semicolon|Other) Of Line End ("char") EOLOther (boolean) Quotes Enclosing Quotes|Strip Strip If no arguments are given, given, are arguments no If name. Relative paths are interpreted relative to the loca interpretedrelative paths are name. Relative Directory Current The path can be a literal path (absolute or relative) Opening a data table a data Opening glo-a to reference the assign you will Usually table. to the data a reference tabledataa returns Opening The usual argumentlaterforbal use. for script); use an unsaved (for JMP application or the Any of the following methods of beginning to work work to of beginning methods Any of the following JSL has and fullto the values JSL properties access of a data tables, viewtheir proper close Once you’ve gotten a data table a gotten you’ve Once reference to the data table object. Objects thatreference can act on messages will be a common theme in this or op to create how seen you’ve as as soon book, so how objects and messages work. messages work. and objects how window in the front. If you have made have then changes, If in the you front. window whole ta JMP always keeps the may expect. Since you If a data table with that path is already open, then open, is already that path table with a data If the whole file. text file a Importing data from you want to import If data from a text file, the “JSL Building Blocks” chapter Blocks” the “JSL Building For information on using POSIX filenames and the filenames on using POSIX information For typically use a relative path to open path to typically use a relative run from a folder inside JMP’s folder, such as th folder, run a from folder inside JMP’s Getting a data table object Data table basics Chapter 5 116 Data Tables Chapter 5 Data table basics

Labels|Table Contains Column Headers (boolean) Year Rule|Two digit year rule ("10-90"| "19xx"| "20xx"| Custom) Column Names Start|Column Names are on line (number) Data Starts|Data starts on line (number) Flags (number) Custom Rule (name) Lines to Read Use Apostrophe as Quotation Mark For example, open("c:\test.txt", End of Field(comma), Labels(0), columns(studentName=character(12), age=numeric(14))); or: open("c:\test2.txt", End of Field(Other), EOFOther ("|"), Labels(1), columns(studentName=character(12), age=numeric(14))); The options for Open: Column names and lengths You can specify column names, types, and field widths with a Columns argument, e.g. columns(studentName=character(12), age=numeric(14)) in the example above. Note that if you specify settings for a column other than the first column in the file, you must also specify settings for all the columns that precede it. For example, You want to open a text file that has four columns, Name, Sex, Age, and ID, in that order, and you want to set Age to numeric(2). You must also set Name and Sex, and you must list them in the same order: columns(Name=character(15), Sex=character(1), Age=numeric(2)) You are not required to specify the settings for any columns that follow the one you want to set. Strip Quotes Boolean. Specifies whether to remove quotation marks from string values. When saving spreadsheet-style data in text format, most programs, including JMP, enclose string values inside double quotation marks ( " ). This ensures that when another program imports the text file, any spaces, tabs, or commas that are meant to be part of a string value are not misinter- preted as field delimiters. For example, a string value such as John Doe would be interpreted as two separate strings, John and Doe, if space were the field delimiter. But "John Doe" inside quotation marks would be interpreted as a single string, because when most programs including JMP read a quotation mark, they disregard any delimiter characters and keep reading until they encounter the second quotation mark. However, since you don’t usually want those double quotation marks to be part of the value (e.g., you want John Doe, not "John Doe", in the data table), JMP provides an option Strip Quotes. If you choose this option, JMP respects the quotation mark rules but removes the marks from the values. Warning: text import in JMP 5 and later is different from JMP 3 and earlier. In version 3, delim- iter characters within quoted string were only ignored if they were not the chosen delimiter char- acter. For example, if you chose “space” as the delimiter, you could safely use tabs, commas, and semicolons inside quoted strings, but you could not use a space inside a quoted string. In version 5 Scripting Data Tables

. 117 . Note: , or EOLOther 20xx , Data Tables EOFOther Specifies the charac- the Specifies 19xx Data table basics , 10-90 of-line or end-of field. For example, of-line or end-of field. For command. command. Open specify the starting line for column names. line starting specify the Specifies the character(s) used to separate to separate used the character(s) Specifies ypical for Macintosh text files), LF for linefeeds text files), ypical for Macintosh ree as line delimiters. Other adds another charac- adds Other as line delimiters. ree des are invisible data that enable the Finder to the Finder data that enable invisible are des delimiter is Tab. Other adds another character of adds Other Tab. delimiter is character. the end-of-line Declares apostrophes as quotation marks. marks. quotation as apostrophes Declares s dates in a custom way. a s dates in with text importfor JSL. and also Comma | Semicolon | Other | None) | Semicolon Comma specifies the specifies the starting data. line for specifies the year rule. Options are are Options rule. year the specifies characters into characters left and right curled quotation marks “ ”. These " specifies a special character a special as the end- specifies specifies the specifies the asterisk as Specifies the number of lines to read. the number of lines to Specifies specifies JSL that handle JSL that specifies Boolean. Indicates whether the first line of the text file contains column labels or not. column file contains text whether the first line of the Boolean. Indicates Note that specifying Other does not block the default action, but adds to it. butdefault adds action, does not block the that specifying Other Note ter(s)field usedfields. The default to separate characterwith the Specify separator. as a record interpreted tobe your choice Space uses a single space as a delimiter, while Spaces uses two or more. or two uses while Spaces delimiter, a space as a single uses Space special problems will cause characters EOLOther("*") Custom. en the chosen delimiter, as long as the value is is as long as the value delimiter, chosen even the to ignore improved was import text 4 and above, quotation marks. inside double that automatically con- feature quotes” have a “smart processors Another warning:word many verts double quotation mark records. The choices are CR for carriage returns (t returns carriage CR for The choices are records. with character the Specify separator. a record as to be interpreted ter of your choice (typical for UNIX text files), or CRLF for both carriage andreturns linefeeds (typical for Win- tointerpret default all th The is text files). dows Custom Rule Column Names Start|Column Names are on line on Names are Names Start|Column Column Data Starts|Data Starts on line Lines to Read Mark Quotation as Apostrophe Use sasxpt=open("carpoll.xpt"); sassd2=open("class.sd2"); sasdbf=open("bigclass.dbf"); xls=open("bigclass.xls"); csv=open("book1.csv"); End of Field(Tab | Space | Spaces | Spaces | | Space End of Field(Tab EOLOther EOFOther, Labels rule digit year Rule|Two Year End of Line(CR | LF | CRLF | Semicolon | Other) Semicolon | LF | CRLF | End of Line(CR On Windows, JMP relies on the usual three-letter filename extensions (e.g., .XPT, .XLS, etc.) to iden- etc.) to .XLS, .XPT, (e.g., extensions filename three-letter the usual on JMP relies Windows, On tify to interpret the type of file examples: and how its contents. Some Importing other file types Importing other file import the other supportedalso file types through can JMP On Macintosh, JMP relies on the Macintosh Type and Creator codes (if present) and secondarily on and codes (if present) and Creator Type on the Macintosh JMP relies Macintosh, On co and Creator filename extensions. (Type three-letter to theicon corresponding application correct display a file with the that created it; files with generic the filename extensions. should have system) other from obtained files on often appear (such as icons Chapter 5 118 Data Tables Chapter 5 Data table basics

Open Database Open Database opens a database using ODBC and extracts data into a JMP data table. See the “Pro- duction Environments” chapter.

Starting a new data table You can start a new data table, or start a new data table and store its reference in a global. In either case, you can specify a name for the table as an argument. New Table(); dt=New Table("myName.jmp"); If you want to avoid a window appearing when you create a new data table, use the invisible key- word. For example, to create an invisible table Abc with one column of ten rows, dt=newTable("Abc", invisible, newColumn("X"),addRows(10));

Note: To prevent “lost” data tables created invisibly, you can only create an invisible data table if you assign it a reference. If you do create an invisible data table without a reference, JMP immediately destroys it, so any further uses of the table result in errors.

Tip: Once you are finished with an invisible data table, do not forget to close it. Otherwise, it will remain in memory until you quit JMP.

More ways of opening data You can open data tables that are accessible through a webpage: open("website url", ) The website URL is a quoted string that exactly describes the internet location of a JMP data table. Add the extension (for example, jmp) as an unqouted named argument if the URL for the data table does not have the .jmp extension. Note that the URL is case sensitive. You can import data the same way. For example, specify text for a text import using your text import preferences. open("http://www.sas.com/", text); If you do not add the text argument, the web page is returned as a string. Additional formats include csv, script, and journal.

Objects and messages Many of JMP’s capabilities are performed by scriptable objects within JMP that know how to execute tasks relevant to themselves. Objects are entities that, once created, know how to do certain things for themselves. A JMP data table is one such object. To work with an object from JSL, you send a message to the object, asking it to perform one of its tasks. Messages are commands that can only be understood in context by a particular type of object. For exam- 5 Scripting Data Tables 119 to dt Data Tables Data table basics creating or opening the creating , and so on. Most of these of these Most on. and so , Sort , then how to send a , thenmessage how to the ref- , 182 in the “Scripting Platforms” 182 in the “Scripting Platforms” reference kind of object, each message’s effect will be deter-effect object,kind of each message’s operators, in addition to ssagesyoucansend to data tables,orcol- or rows sending many messages to the globals is most con- most globals is the many messages to sending —a reference to one of JMP’s kinds of scriptable scriptable of kinds JMP’s of to one reference —a e objects can understand. A later section examines section A later objects can understand. e uent chapters explore uent chaptersanalysis and explore graph platform New Column table open. Notice that each one begins with an with begins each one that table open. Notice , easier if you only have one message to send: have only you if easier to the object. (This uses the placeholder manual Save y in which JSL is heavily context-dependent. heavily context-dependent. JSL is which y in use by the second Bivariate object: Bivariate second the use by statement (or if you opened it through the menus): through the it opened statement (or if you can also take a scriptable object reference as an argument. For example, this as an argument.For takealsocan a scriptable object reference New Table or Open function: , discusses references to analysis platform objects. , discusses references Send dt=Open("$SAMPLE_DATA/Big Class.jmp"); dt=Open("$SAMPLE_DATA/Big dt<

current data table()<

Running a script attached to a data table The Run Script command, when sent to a data table, finds a named property (i.e., a script) and runs it as a JSL script. For example, if you open Big Class.jmp and submit the following, the script named “Distribution” is run. Current Data Table()<

Closing a data table To close a data table, use a Close command with the data table’s reference as the argument. If there are unsaved changes, an alert dialog asks whether to save changes. Such a prompt suspends execution of a script; to avoid being prompted, either send a Save message first, or include a filename argument for saving in the Close message. To close without saving or being prompted, include No Save in the com- mand. dt=Open("$SAMPLE_DATA/Big Class.jmp"); close(dt); close(dt, save("myFile")); close(dt, No Save);

Reverting to a saved data table To revert to the most recently saved data table, send the Revert message to the data table. Before reverting, JMP asks whether the current data table should be saved.

Counting open data tables N Table() returns the number of open data tables.

Getting and using a list of open data tables If you want to do something to all the data tables that are currently open, you can use N Table to get a list of references to each one: openDTs = List(); For( i = 1, i <= N Table(), i++, Insert Into( openDTs, Data Table( i ) ); ); openDTs now is a list of references to all open data tables. You can send messages to any one by using openDTs(n). You can use a for loop to send messages to all of the open data tables. This loop adds a new column named My Column to each open data table. For( i = 1, i <= N Items(openDTs), i++, 5 Scripting Data Tables 121 is Close Data Tables Data table basics t exist yet. Once created, these objects these created, Once yet. exist t r, because the objects can’t delete themselves. because the objects can’t r, or Show Show menu s all result s all result , and these Graph Tables panes of the data items are listed here here listed items are and and [Action] . e items available in the e items available are commands to create objects that don’ objects create to commands are Row lists the a data messages [Scripting Only] [Scripting Graph Open Analyze , and entries show the menus in show entries is a command that takes any and and Column table()); Class.jmp"); openDTs[i]<

Data table objects contain column objects, which can handle messages of their own. The later section “Manipulating columns,” p. 145, discusses how to refer to column objects, show their properties, and send them messages. Show Properties also works with platforms and display boxes; see “Learning the messages an object responds to,” p. 184 in the “Scripting Platforms” chapter and “Learning what you can do with a display box,” p. 232 in the “Display Trees” chapter. Some general tips that also apply to data table objects appear in “How to interpret the listing from Show Properties,” p. 185 in the “Scripting Platforms” chapter. Refer to the JSL browsers in the Index pane of the JMP Starter Window for a brief overview of any item.

Messages for data tables This section details the messages you can send to data tables. Previous sections discussed how to start or open data tables and how to send basic messages to them. The next section discusses data table column objects and their messages.

Naming, saving, and printing Before saving, you might want to give the table a name, or change it to a new name. The Set Name message does this, and its argument is just a filename in quotation marks, or else something that evalu- ates to a filename. dt << set name("new big class.jmp"); There is a command to obtain the name: name = dt << Get Name; // to retrieve the name To save, you send a Save message. You can also specify the filename (and a complete path) as an argu- ment to a Save message, if you don’t want to do a separate Set Name message. The syntax is: dt << Save (<"pathname"> <, "file type"> <, ); Some examples: dt << save(); // Save using the current name dt << save("c:/mydata/new big class.jmp"); // Save a new file dt << save("MyTable", JMP(5)); // Save as JMP 5 table On Windows, saving with a .txt extension exports according to the current Text Export preferences. On the Macintosh, append the file type as a second argument to the save function when saving to a type other than JMP. Some Macintosh examples are: Valid file types are: current data table() << save("New Big Class.txt", Text); current data table() << save("New Big Class.sas", SAS); current data table() << save("New Big Class.jrn", Journal); current data table() << save("New Big Class.jsl", Script); You can print the current data table by sending it a Print Window message. 5 Scripting Data Tables 123 com- Data Tables NewWindow() ication in square brackets in square ication Messagestables for data enclosing the search specif the search enclosing ts the display tree with just a picture. picture. with just a the display tree ts the journal and journal window commands. This parameter “freezes” commands.the journal This parameter and“freezes” journal window returns a reference to the display box at the top of the current journal display current display box at the top of the to the a reference returns ButtonBox("Test One",Dialog("Hi there1")), One",Dialog("Hi ButtonBox("Test there2")) Two",Dialog("Hi ButtonBox("Test Current Journal()<); box Journal()<

Current Journal()[“Parameter Estimates”]<

Creating and deleting columns

New columns To add a new column to an existing data table, send a New Column message to a data table reference. The first argument (required) is the column’s name, which must either be a name in quotation marks or else an expression evaluating to that. Further arguments are optional and set attributes for data type (Numeric, Character, or RowState) and analysis type (Continuous, Nominal, or Ordinal). You may also include Values, Formula, and other script messages appropriate to a column. dt<

Deleting columns To delete columns, send a Delete Columns message and specify which column or columns to delete. To delete more than one column, list the columns as multiple arguments or as a list. Without an argu- ment, Delete Columns deletes the currently selected columns. dt<

. 125 New Table New Data Tables Current Data Table Data Current . You can either assign a can either assign . You give more details. more give 127 Messagestables for data Row() . message. . 124 it, or when you create it with it create it, or when you t up a data table as the “current data table,”t up aspec- data table as the “current Open e steps separately, puts them together with a few a them together with puts separately, steps e For Each Row() For Each message. message. See more information in “Manipulating col- in “Manipulating information more message. See when you when you Get Selected Columns Selected Get , and “What is the current row?,” p. row?,” and “What, current the is 127 Select Rows Select Set Selected Set current data table current or else use the iterative command command iterative use the or else . 145 Row() <

Setting or getting values by column name The easiest way to refer to a column is by its name. To prevent ambiguity in case you have a global vari- able that also uses the same name, you can use the : prefix operator to scope it as a column name. It works without the prefix, but we recommend the prefix. To set the cell of the current row of the col- umn name, use the assignment statement with the column name on the left (it is an L-value). :name = "Archibald"; If you want to get the value, just specify the name, preferably scoped with the colon. show(:name); myGlobal = :name; If you want to set a specific row of the column, rather than the current row, use a subscript with the row number. :name[rownum] = "Archibald"; rowValue = :name[rownum]; By convention, an empty subscript refers to the current row, so :name[ ] is the same as :name.

Confusion alert! Be careful that you are subscripting to a row of the table that exists. The default row number is zero, so statements like :name that refer to row zero gener- ate an Invalid Row Number error.

Putting it all together (example) Here you first open a table to make it the current data table, then use For Each Row to use every row in turn as the current row, and refer to a column to get its values. dt=open("$SAMPLE_DATA/Big Class.JMP"); for each row( print(:age) );

Other ways There are other ways to specify all three elements (the data table, the row, and the column). Some of these involve the indirect reference to a column through a column reference, as covered in detail in “Manipulating columns,” p. 145. All the following lines obtain the value of row 2 of column age. :age[2]; // returns value of age in row 2: 12 column("age")[2]; // same but indirectly thru column reference col=column("age"); col[2]; // same but with a stored column reference Row()=2; col[]; // empty subscript means current row Confusion alert! When referring to columns indirectly—using column references—a subscript is required to refer to the individual values. Without a subscript, the refer- ence is to the column object as a whole.

You can specify all three items directly by using the : infix operator and a subscript: dt:Age[2] = 12; // table, column, and subscript If you want to target multiple rows, you can use subscripts with a list or matrix of row numbers. if (age<13,print(row())); if (age[i]<13,print(i)); 5 Scripting Data Tables 127 94 in 94 in 415 in in 415 Data Tables operator to avoid : is an example of an an is Messagestables for data Row( ) a data table (or matrix; see the “Matri- in a table is row 1, so row 0 is essentially not a a not is essentially 0 row so 1, is row table a in first introduces basic concepts and some useful s value unless you place an assignment it before the same script submitted a few lines at a time. default (row 0, or no row). Therefore, a script sub- Therefore, 0, or no row). (row default portion of a script you select and submit. After the wise, though, a script is performed on the current current the performed on script is a though, wise, ult that might look reasonable for the whole datathe whole for ult that might look reasonable ating that are built into JSL (see “Iterating,” p. built into JSL (see “Iterating,” are thatating tics operators, statis and any use and the pre-evaluated the data table only. Some obvious exceptions are the are exceptions obvious Some only. the data table obal script variable. See “Stored expressions,” p. expressions,” “Stored obal See script variable. ), JSLfor operators has ), iterating through data tablerows, mn on the current row. Use the prefix Use row. mn on the current operator to refer unambiguously to a data unambiguously column to a refer and the operator to : .) Summarize operator to get or set the current row number. number. row set the current get operator or to operators count the rows and columns in and columns in the rows count operators Row() , etc.) to set its value. NCol += , and = expression in JSL: an operator that returns it JSL: an operator that returns in expression NRow NRow(dt); // number of rows // number NRow(dt); :sex; //returns "" //returns :sex; . //returns :age; default) by (0 row current of the number the //returns Row(); in x row number the current //stores x=Row(); current row 7th the //makes Row()=7; 12 //returns :age; row()=7; age[i] = 3; = age[i] = 14; age[{3,12,32}] a list in results // = age[{3,12,32}]; list a matrix in results // vector=age[1::20]; the “Advanced Concepts” chapter Concepts” “Advanced the the can use You operator ( L-value ambiguity (to force the name to be interpreted as a data tableas column name). to be interpreted the name force (toambiguity of data table columns by analysis platforms. Other Inother row. you take action to set a current words,. Unless is done on no rows default, an operation by col- a example, the lack of data. For due to values get missing you set of rows, specify some or to row colu that of the value returns name umn row of the data table. of the data row row? current is the What row first 0. The number is row the current default, By script executes, the current row script to settingexecutes, row resets the the current Note that the current row setting only lasts for the row that the current Note mitted all at once can produce different results mitted allfrom results at different once can produce columns? and rows How many The Why? This default protects you from getting a res protects you from accidentally overwriting data val- data overwriting accidentally from you protects also It only one row. on buttablebased is actually protec- complete (More most circumstances. names under to ambiguous assignments making ues when or infix prefix the using had by tion is Iterating on rows of a table of on rows Iterating addition operators for iter to In the programming chapter Functions” the “Programming groups, or conditional selections of rows. This section This rows. selections of or conditional groups, operators. of row on executes the current script Generally, expressions inside formula columns, ces” chapter). ces” prefix :: unambiguously operator to refer to a gl Chapter 5 128 Data Tables Chapter 5 Messages for data tables

NCol(dt); // number of columns

For Each Row To iterate a script on each row of the current data table, put For Each Row around the script. For Each Row( if(:age>15, show(age)) ); A typical use is for setting rowstates without creating a new formula column in the data table. The scripts below are similar except that the first one creates a rowstate column and the For Each Row ver- sion simply sets the rowstate without creating a column. new column("My Rowstate", rowstate, formula( color state(age-9)) ); for each row(color of(rowstate())=age-9); To iterate a script on each row meeting a specified condition, combine For Each Row and If. for each row(marker of(rowstate())=if(sex=="F",2,6)); Break and Continue can be used to control execution of a For Each Row loop. For details on using these two functions, see “Break and Continue,” p. 96 in the “Programming Functions” chapter.

Dif and Lag JMP has two special operators that are useful for statistical computations, particularly when working with time series or cumulative data. Lag returns the value of a column n rows before the current row. Dif returns the difference between the value in the current row and the value n rows previous. The fol- lowing are equivalent: dt<

Comparing two data tables (example) Here is a little program to compare two data tables and show entries that differ: dt1=open(); dt2=open(); nr = min(nrow(dt1),nrow(dt2)); nc = min(ncol(dt1),ncol(dt2)); 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,show(i,ColumnName(j),v1,v2)); )); You could make a fancier program to compare data tables that would also check whether they have the same numbers of rows and columns, whether the columns share the same names, and whether they have the same row states in effect. 5 Scripting Data Tables 129 Data Tables , and each of these take a , Messagestables for data Quantile also takes a argument for speci- second ta table and stores them in global vari- them in globaltableta and stores , and StdDev calculations. If all data are excluded, Summarize calculations. allIf Summarize data excluded, are Quantile , statement is included, then a list of subgroup stats statement is is included, then a list of subgroup ) Max , , as discussed in “Build your own displays from scratch,” scratch,” from displays own your in “Build discussed , as Min , Summarize . groupvar Mean , =By( TableBox Sum does not require a column argument, but it is often useful to specify a specify to useful often but it is argument, column a not require does group, the results are a list and six matrices: six list and a are results the group, , which gathers summary them in a new data statistics and presents table). , name By Count Count . . 0.1 for the 10th percentile. for the 10th percentile. . 0.1 e.g Summary command gathers summary for a da statistics name 1.988059594776032, 4.041451884327343, 4.163331998932229] 4.041451884327343, 1.988059594776032, a), stringColBox("Age", c), NumberColBox("Count", sumHt), NumberColBox("Sum", meanHt), NumberColBox("Mean", minHt), NumberColBox("Min", maxHt), NumberColBox("Max", sdHt), NumberColBox("SD", q10Ht))); NumberColBox("Q10", 64.33333333333333, 66.66666666666667] 64.33333333333333, Excluded rows are excluded from from excluded are rows Excluded q10Ht:[51, 56, 61.3, 62, 60, 62] 62, 61.3, 56, q10Ht:[51, minHt:[51, 56, 61, 62, 60, 62] 60, 61, 62, 56, minHt:[51, 70] 68, 69, 67, 65, maxHt:[66, 2.367712103711172, 3.039423504234876, sdHt:[5.083235752381126, TableBox( a:{"12", "13", "14", "15", "16", "17"} "16", "15", "14", "13", a:{"12", 3, 3] 12, 7, 7, c:[8, 200] 193, 452, 770, 422, sumHt:[465, 64.57142857142857, 64.16666666666667, 60.28571428571428, meanHt:[58.125, a=by(age), c=count, sumHt=sum(height), meanHt=mean(height), minHt=min(height), maxHt=max(height), sdHt=stddev(height), q10Ht=quantile(height,.10)); Summarize NewWindow("Summary Results", NewWindow("Summary show(a, c, sumHt, meanHt, minHt, maxHt, sdHt, q10Ht); sdHt, maxHt, minHt, meanHt, c, sumHt, show(a, summarize( 258 in the “Display Trees” chapter Trees” “Display 258 in the Named arguments are arguments are Named p. Note: fying which quantile, You can formattheusing results You Since the script included a the Since The The ables (as opposed to (as opposed ables assigned to each assigned to returns lists of missing values. If all data have been deleted (there are no rows), Summarize returns returns Summarize no rows), are havedata alldeleted (there beenvalues. missing of If lists returns empty lists. Class: Big using example, For data column argument. a If column to count the number of non-missing values. Summarize Chapter 5 130 Data Tables Chapter 5 Messages for data tables

Figure 5.1 Results from Summarize

With a little work, you can combine total and grouped results in the window: summarize( tc=count, tsumHt=sum(height), tmeanHt=mean(height), tminHt=min(height), tmaxHt=max(height), tsdHt=stddev(height), tq10Ht=quantile(height,.10));

insertinto(a,"Total"); c=c|/tc; sumHt=sumHt|/tsumHt; meanHt=meanHt|/tmeanHt; minHt=minHt|/tminHt; maxHt=maxHt|/tmaxHt; sdHt=sdHt|/tsdHt; q10Ht=q10Ht|/tq10Ht;

NewWindow("Summary Results", TableBox( stringColBox("Age",a), NumberColBox("Count",c), NumberColBox("Sum",sumHt), NumberColBox("Mean",meanHt), NumberColBox("Min",minHt), NumberColBox("Max",maxHt), NumberColBox("SD",sdHt), NumberColBox("Q10",q10Ht))); 5 Scripting Data Tables 131 Data Tables , or data about the data. , Messagestables for data metadata Big Class.jmp there is a By clause, or scalars if there is no By no By is clause, or scalars if there is a By there as the source of the data, comments about each variable, scripts for group, the result in each name is a single value. Compare: Compare: value. a single is name in each result the group, By use a not Summarize with Total Summarize "17"}, {"F", "M", "F", "M", "F", "M", "F", "M", "F", "M", "F", "M"}} "F", "M", "M", "F", "F", "M", "F", "M", "F", "M", {"F", "17"}, c:[5,3,3,4,5,7,2,5,2,1,1,2] g:{{"12", "12", "13", "13", "14", "14", "15", "15", "16", "16", "17", "17", "16", "16", "15", "15", "14", "14", "13", "13", "12", g:{{"12", c:40 sumHt:2502 meanHt:62.55 minHt:51 maxHt:70 sdHt:4.242338493971897 q10Ht:56.2 c=count, sumHt=sum(height), meanHt=mean(height), minHt=min(height), maxHt=max(height), sdHt=stddev(height), q10Ht=quantile(height,.10)); show(c,sumHt,meanHt,minHt,maxHt,sdHt,q10Ht); sex), c=count()); Summarize(g=by(age, c); show(g, summarize( // a=by(age), clause. variables of various observation data—measurements data table is to store for a JMP main purpose The JMP data tables can also store r, Howeve subjects. of set on a specific with the data, analysis roles for columns, and so working on. The statistical results of Summarize are always are The matrices if statistical results of Summarize Summarize supports multiple By-groups. For example, on For supportsBy-groups. multiple Summarize in results include information such Metadata When you do you When Figure 5.2 Working with metadata Working Chapter 5 132 Data Tables Chapter 5 Messages for data tables

Tools for working with metadata are found in the Table pop-up menu in the upper left pane of a data table, in the Column Info dialogs, and so on. This section discusses how to work with metadata in JSL.

Table variables Table variables are for storing a single text string value, such as “Notes” in Big Class. To see how vari- ables work, first get its existing value and assign that to a global, oldvar, by sending a Get Table Variable message: dt=open("$SAMPLE_DATA/conditional logit.jmp"); dt<

Properties/Scripts A property is similar to a table variable, but it is used to store an expression, e.g. a JSL script. For exam- ple, if you do an analysis and then use the Save Script to Data Table command from the report’s pop-up menu, it saves a script named for the analysis platform in the data table. In the data table win- dow, you can double-click the property name to see its script value, or you can select Run Script from its pop-up menu to execute the script. Also, when you run Design of Experiments (DOE), the resulting data tables automatically include properties called Model to launch Fit Model with the appropriate design. You can save a table property named QC Alarm Script or QC Test Alert to set up an alert script for control charts; see “Alarm scripts,” p. 218 in the “Scripting Platforms” chapter. JSL has New Table Property, Set Property, and Get Property messages. dt<.lproj/Builtin Contents/Resources/.lproj/Builtin pport Files folder for your locale, which is within which is folder for your locale, pport Files New Table Property Table New ation package. Right-clic construct the information in a datawith table , for ways to store extra information 148tostore about, for ways columns. ). with a property or variable . Then navigate to . folder running. willdependtheon locale you are every time you start JMP, name it every starttime you JMP, col Save Script to Data Table to Data Save Script Current Data Table() Data Current *.lproj stored as a property as of the a property stored data tabl or column , or else store the script using a script using the store , or else folder: message to message dt On Open On Sort On Open On . The name of the of . The name to use for simple demonstrations of each platform. Use Name as a label, a label, Name as Use platform. of each demonstrations for simple to use Table New and Ys"), as Xs variables of the combination any and New ""), Variable("Oneway", Table New ""), Variable("Distribution", New Height))), Distribution(Column(Age, Property("Distribution", Table Show Package Contents Package Show : New Table("Class", Add Rows(19), New Table Variable("Notes", "Example data "Example Variable("Notes", Table New Rows(19), Add Table("Class", New table()<\Builtin Scripts Scripts dt<

Table Property("Oneway", Oneway(Y(Height), X(Age), Quantiles(1), Box Plots(1))), New Column("Name", Character, Nominal, Values({"BARBARA", "ALFRED", "ALICE", "CAROL", "HENRY", "JAMES", "JANE", "JANET", "JEFFREY", "JOHN", "JOYCE", "JUDY", "LOUISE", "MARY", "PHILIP", "ROBERT", "RONALD", "THOMAS", "WILLIAM"})), New Column("Sex", Character, Nominal, Set Property("Notes", "Explore data adventurously"), Values({"F", "M", "F", "F", "M", "M", "F", "F", "M", "M", "F", "F", "F", "F", "M", "M", "M", "M", "M"})), New Column("Age", Numeric, Nominal, Set Property("Notes", "Explore data adventurously"), Values([13,14,13,14,14,12,12,15,13,12,11,14,12,15,16,12,15,11,15])), New Column("Height", Numeric, Continuous, Set Property("Notes", "Explore data adventurously"), Values([65.3,69,56.5,62.8,63.5,57.3,59.8,62.5,62.5,59,51.3,64.3,56.3, 66.5,72,64.8,67,57.5,66.5])), New Column("Weight", Numeric, Continuous, Set Property("Notes", "Explore data adventurously"), Values([98,112.5,84,102.5,102.5,83,84.5,112.5,84,99.5,50.5,90,77,112, 150,128,133,85,112])))

Controlling formula evaluation The message Suppress Formula Eval takes a boolean argument to specify whether formula evalua- tion should be suppressed or not. You might want to suppress evaluation if you plan to make numerous changes to the data table and don’t want to wait for formula updates between steps. dt<......

For example, newTable("A", Set Matrix([1 2 3, 4 5 6, 7 8 9])); creates a new data table named A with three rows and three columns. dt=New Table("B"); dt<

Commands from the Rows menu This section describes the messages for working with the rows in a data table. Row messages are directed to a data table reference, and most act on the currently selected rows. Many of the row mes- sages would not usually be useful in scripts, unless you were writing demo scripts that simulate interac- tive use of JMP.

Adding rows To add rows, send an Add Rows message and specify how many rows, and (optionally) after which row to insert them. The arguments can either be numbers or expressions that evaluate to numbers. dt=Open("$SAMPLE_DATA/Big Class.jmp"); dt<

dt<

a = {xx=20,cc="Miami"}; dt<

b={{xx=17,cc="San Antonio"},{xx=18,cc="Houston"},{xx=19,cc="Dallas"}}; dt<n-x,i--, n=NRow(dt); dt=Open("$SAMPLE_DATA/Big Class.jmp"); dt=Open("$SAMPLE_DATA/Big 10 row deletes //selects, rows; selected(rowstate(10))=1;dt<

To select rows according to data values, use Select Where, specifying a logical test inside the paren- theses. You can use all the usual functions and operators from the formula calculator, which are docu- mented in the “JSL Operators” chapter and summarized in “Data Tables, Rows, and Columns,” p. 512 in the “JSL Syntax Reference” appendix. For example, using Big Class.jmp, you might use: dt<

Moving Rows These commands move the currently selected rows to the indicated destination point. dt<

Finding Rows These two commands return a matrix of row numbers: result = dt<=16) result = dt<

Assigning colors and markers to rows You can use the Colors and Markers messages to assign (or change) colors and markers used for rows. These settings mostly affect graphs produced from the data table. Both messages expect numeric argu- ments to pick which color or marker to use; how numbers correspond to colors and markers is summa- rized in “Colors and markers,” p. 165. dt<, , ... ); ... )>, ( ... Filter , ... 13)<13)<13); dt<

Setting and getting attributes A collection of message pairs for data table columns let you control all the various attributes or charac- teristics of a column, including its name, its data, and its metadata. The messages come in pairs, one to “set” or assign each attribute and one to “get” or query the current setting of each attribute. Hide, exclude, label, and scroll lock for a column can be activated and deactivated through scripting. Submit a 1 to turn the column attribute on, and a zero to turn it off. For example, the follow- ing four lines of code scroll lock a column called Name, add it to the list of label columns, unexclude it, and unhide it. column("name") << scroll lock(1); column("name") << label(1); column("name") << exclude(0); column("name") << hide(0);

Confusion alert! All the messages to set various parameters (e.g. Set Name, Set Values, Set Formula) start with Set, but the word Set is optional for all but Set Name (recall that Name is already used for something else—the command that lets you use unusual characters in a name). Use whichever form you prefer or find easier to remember. The corresponding messages to retrieve the current value of a parameter (e.g. Get Formula) are the same except they start with Get instead of Set, and the word Get is not optional.

To clear a column selection, submit a Clear Column Selection message to the data table. dt<

Names Set Name lets you name or rename a column, and Get Name returns the name for a column. col<

Values Similarly, Set Values sets values for a column. If the variable is character, the argument should be a list; if numeric, a matrix (vector). If the number of values is greater than the current number of rows, the necessary rows are added. Get Values returns the values in list or matrix form, and Get As Matrix is a synonym. col<

column("age")<

col<

Confusion alert! Do not confuse the Format message for columns with the Format operator for converting numeric values to strings according to the format specified (typically used for date/time notation as described in “Date/Time Operators,” p. 79 in the “JSL Operators” chapter). Sending a message to an object has a very different effect from using a function that might happen to have the same name.

To get the current format of a row, submit a Get Format message. col<

Roles You can Preselect Roles. Choices are None, X, Y, Weight, and Freq. See “Objects within analysis objects,” p. 187 in the “Scripting Platforms” chapter. Get Role returns the current setting. col<

Formulas Similarly, you can set, get, and evaluate a formula for a column: col=New Column("Ratio"); // creates column and stores its reference col<

When formulas are added, they are scheduled to be evaluated in a background task. This is a problem for scripts if they depend on the column having the values while the script is running. To force a single column to evaluate, you can send an Eval Formula command to the column. You can even do this inside the command to create the column, right after the Formula clause, for example: dt<

x col<

Setting, retrieving, and removing column properties Data columns have numerous optional metadata attributes that can be set, queried, or cleared using the messages Get Property, Set Property, and Delete Property. The name of the property in ques- tion is always the first argument for Set Property, and what is expected for subsequent arguments depends on which property you’re setting. Get Property and Delete Property always take a single argument, which is the name of the property. Get Property returns the property’s settings, while Delete Property completely removes the property from the column. col<

Table 5.2 Properties for data table columns (Continued) Usage Property Arguments expected Set in DOE and Response Limits List of parameters and their values. Choices for Goal are used in desirability Maximize, Match Target, Minimize, None. Other profiling. parameters take numeric value and desirability arguments, e.g. col<

Lock To lock or unlock a column, use Lock or Set Lock with a boolean argument. Get Lock returns the current setting. col<

Scripts Get Script returns a script to create the column: New Column("Ratio",SetFormula( :height/ :weight)); column("ratio")<

Row State operators There is a special data element type called a row state for storing various attributes in the data table, such as whether a row is selected or not, excluded or not, hidden or not, and labeled or not; which 5 Scripting Data Tables 155 still are .) if you’re inter- if you’re .) Hide Data Tables Hide and and atesonce to get the at Row State Row State operators and AsRowState Exclude . (To omit points from plots, use omit points from . (To Exclude plots er labels, or the values from a designated a from er labels,values or the markers to the markers distinguish points in scatter- . (To omit points from reports and charts, use and reports from points omit . (To in a data table have. These six attributes are actu- These six in a data table have. attributes are can also use several row st can also row use several P works with your data. The table below explainsPtable with your data. works below The and hue to use for graphs. Row states can be freely states can be freely and hue to use for graphs. Row charts r detail how to work with row states in scripts. in scripts. states row with to work r detail how JMP’s analyses, charts,plotsand JMP’s . . To omit points use allfrom both results, . To vice versa . To omit points from all results, use both all results, from omit points . To reports and charts). Results are the same as if you had never entered those rows in those rows entered had never you if the same as are and charts).reports Results still included points in are the table. However, Exclude Hide Label column, on points in scatterplots. and spinning plots. included in text reports and reports included in text plots and spinning plots. and spinning plots fects you want. Row states and how they affect they how and states Row Labeled numb labeled, JMP places row are rows If Hidden the rows However, them in plots. show JMP doesn’t hidden, are rows If Row statesRow Excluded results affect they How JMP omits them calculations for from statistical analyses excluded, are (text rows If Marker those JMP uses markers, have rows If Color scatterplots points in the distinguish colors to those uses JMP colors, have rows If in expressions. First this section shows what row row what shows section this First ested.) expressions. JSL as a separate type in state values supports row it examines in greate then and states do in JMP, do states row What way JM they change the set up, states are row Once each row state separately, but keep in mind that you in mind that you but keep state separately, each row combination of ef Table 5.3 marker to use for graphs, and which color, shade, shade, marker to use for graphs, and color, which state is a collectionsix attributesofthat all rows Row defined numerically is invisible and states are row (How ally packed into a singlenumberinternally. unimportantbutfor you can find most users, the formalunder definitions converted and to integers What are row states? row What are Chapter 5 156 Data Tables Chapter 5 Row State operators

Table 5.3 Row states and how they affect JMP’s analyses, charts, and plots (Continued) Row states How they affect results Selected If rows are selected, JMP highlights the corresponding points and bars in plots and charts.

How to assign row states There are several ways to set row states in JMP’s graphical user interface. 1 Manually: select one or more rows in the data table, then select row state choices from the pop-up menus in the Rows pane of the data table. See Figure 5.1. 2 Algebraically: set a rowstate with an expression that evaluates to rowstate number values. Create a formula variable of type Row States, and then choose Copy to Row States or Add to Row States from the pop-up menu for the column. See Figure 5.2. Figure 5.3 Setting Row States Manually

The JSL equivalent would be something like this: dt<