Scripting Guide JMP 12 SAS Institute

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 692

DownloadScripting Guide JMP 12 - SAS Institute
Open PDF In BrowserView PDF
Version 12

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. 2015.
JMP® 12 Scripting Guide. Cary, NC: SAS Institute Inc.
JMP® 12 Scripting Guide
Copyright © 2015, SAS Institute Inc., Cary, NC, USA
ISBN 978‐1‐62959‐482‐8 (Hardcopy)
ISBN 978‐1‐62959‐484‐2 (EPUB)
ISBN 978‐1‐62959‐485‐9 (MOBI)
ISBN 978‐1‐62959‐483‐5 (PDF)
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.
The scanning, uploading, and distribution of this book via the Internet or any other means
without the permission of the publisher is illegal and punishable by law. Please purchase
only authorized electronic editions and do not participate in or encourage electronic piracy
of copyrighted materials. Your support of others’ rights is appreciated.
U.S. Government License Rights; Restricted Rights: The Software and its documentation is

commercial computer software developed at private expense and is provided with
RESTRICTED RIGHTS to the United States Government. Use, duplication or disclosure of
the Software by the United States Government is subject to the license terms of this
Agreement pursuant to, as applicable, FAR 12.212, DFAR 227.7202‐1(a), DFAR 227.7202‐3(a)
and DFAR 227.7202‐4 and, to the extent required under U.S. federal law, the minimum
restricted rights as set out in FAR 52.227‐19 (DEC 2007). If FAR 52.227‐19 is applicable, this
provision serves as notice under clause (c) thereof and no other notice is required to be
affixed to the Software or documentation. The Government’s rights in Software and
documentation shall be only those set forth in this Agreement.
SAS Institute Inc., SAS Campus Drive, Cary, North Carolina 27513‐2414.
March 2015
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 trademarks of their respective companies.
Technology License Notices
•

Scintilla ‐ Copyright © 1998‐2014 by Neil Hodgson .
All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its documentation for
any purpose and without fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright notice and this permission
notice appear in supporting documentation.
NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NEIL
HODGSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

•

Telerik RadControls: Copyright © 2002‐2012, Telerik. Usage of the included Telerik
RadControls outside of JMP is not permitted.

•

ZLIB Compression Library ‐ Copyright © 1995‐2005, Jean‐Loup Gailly and Mark Adler.

•

Made with Natural Earth. Free vector and raster map data @ naturalearthdata.com.

•

Packages ‐ Copyright © 2009‐2010, Stéphane Sudre (s.sudre.free.fr). All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
Neither the name of the WhiteBox nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
•

iODBC software ‐ Copyright © 1995‐2006, OpenLink Software Inc and Ke Jin
(www.iodbc.org). All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
‒ Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
‒ Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
‒ Neither the name of OpenLink Software Inc. nor the names of its contributors may
be used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL OPENLINK OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.

•

bzip2, the associated library “libbzip2”, and all documentation, are Copyright ©
1996‐2010, Julian R Seward. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.

The origin of this software must not be misrepresented; you must not claim that you
wrote the original software. If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is not required.
Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
The name of the author may not be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR “AS IS” AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

•

R software is Copyright © 1999‐2012, R Foundation for Statistical Computing.

•

MATLAB software is Copyright © 1984‐2012, The MathWorks, Inc. Protected by U.S.
and international patents. See www.mathworks.com/patents. MATLAB and Simulink
are registered trademarks of The MathWorks, Inc. See www.mathworks.com/
trademarks for a list of additional trademarks. Other product or brand names may be
trademarks or registered trademarks of their respective holders.

•

libopc is Copyright © 2011, Florian Reuter. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
‒ Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
‒ Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and / or other
materials provided with the distribution.
‒ Neither the name of Florian Reuter nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
•

libxml2 ‐ Except where otherwise noted in the source code (e.g. the files hash.c, list.c
and the trio files, which are covered by a similar licence but with different Copyright
notices) all the files are:
Copyright © 1998 ‐ 2003 Daniel Veillard. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the “Software”), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Daniel Veillard shall not be used in
advertising or otherwise to promote the sale, use or other dealings in this Software
without prior written authorization from him.

Get the Most from JMP®
Whether you are a first‐time or a long‐time user, there is always something to learn
about JMP.
Visit JMP.com to find the following:
•

live and recorded webcasts about how to get started with JMP

•

video demos and webcasts of new features and advanced techniques

•

details on registering for JMP training

•

schedules for seminars being held in your area

•

success stories showing how others use JMP

•

a blog with tips, tricks, and stories from JMP staff

•

a forum to discuss JMP with other users

http://www.jmp.com/getstarted/

Contents
Scripting Guide
1

Learn about JMP
Documentation and Additional Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Formatting Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
JMP Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
JMP Documentation Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
JMP Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Additional Resources for Learning JMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Tutorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Sample Data Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Learn about Statistical and JSL Terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Learn JMP Tips and Tricks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Tooltips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
JMP User Community . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
JMPer Cable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
JMP Books by Users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
The JMP Starter Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

2

Introduction
Welcome to the JMP Scripting Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
What JSL Can Do for You . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Help with Learning JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
The Scripting Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
The Scripting Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Let JMP Teach You JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Basic JSL Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

10

3

Scripting Guide

Getting Started
Let JMP Write Your Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Capturing a Script for an Analysis Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Capturing a Script for a Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Capturing a Script to Import a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Gluing Scripts Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

4

Scripting Tools
Using the Script Editor, Log Window, Debugger and Profiler . . . . . . . . . . . . . . . . . . . . . . . 53
Using the Script Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Run a Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Stop a Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Edit a Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Color Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Auto Complete Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Tooltips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Split a Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Match Parentheses, Brackets, and Braces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Select a Rectangular Block of Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Select Fragmented Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Drag and Drop Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Find and Replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Automatic Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Add Code Folding Markers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Advanced Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Set Preferences for the Script Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Working with the Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Show the Log in the Script Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Save the Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Debug or Profile Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Debugger and Profiler Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Work with Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
View Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Work with Watches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Modify Preferences in Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

Scripting Guide

11

Persistent Debugger Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Examples of Debugging and Profiling Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

5

JSL Building Blocks
Learning the Basics of JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
JSL Syntax Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Value Separators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Global and Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Local Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Named Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Show Symbols, Clear Symbols, and Delete Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Lock and Unlock Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Rules for Name Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Resolving Unscoped Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Troubleshooting Variables and Column Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Troubleshooting Variables and Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Alternatives for Gluing Expressions Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Iterate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Summation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Break and Continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Conditional Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
If . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Match . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Choose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Interpolate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Step . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Compare Incomplete or Mismatched Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

12

Scripting Guide

Inquiry Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

6

Types of Data
Working with Numbers, Strings, Dates, Currency, and More . . . . . . . . . . . . . . . . . . . . . . 123
Numbers and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Unicode Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Path Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Create and Customize Path Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Relative Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
File Path Separators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Date‐Time Functions and Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Date‐Time Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Program with Date‐Time Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Date‐Time Values in Data Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Currency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Hexadecimal and BLOB Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Work with Character Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Concat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Munger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Repeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Pattern Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

7

Data Structures
Working with Collections of Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Evaluate Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Assignments with Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Perform Operations in Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Find the Number of Items in a List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Subscripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Locate Items in a List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
List Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Iterate through a List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Concatenate Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

Scripting Guide

13

Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Construct Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Subscripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
Inquiry Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Comparisons, Range Checks, and Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Numeric Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Transpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Matrices and Data Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Matrices and Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Loc Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Ranking and Sorting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Special Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Inverse Matrices and Linear Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Decompositions and Normalizations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Build Your Own Matrix Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Statistical Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Associative Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

8

Programming Methods
Complex Scripting Techniques and Additional Functions . . . . . . . . . . . . . . . . . . . . . . . . . 219
Lists and Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Stored expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Manipulating lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Manipulating expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Advanced Scoping and Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Names Default To Here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Scoped Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Referencing Namespaces and Scopes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Resolving Named Variable References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Best Practices for Advanced Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Advanced Programming Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
Throwing and Catching Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

14

Scripting Guide

Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Includes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Loading and Saving Text Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Scripting BY Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Organize Files into Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Encrypt and Decrypt Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Additional Numeric Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Derivatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Algebraic Manipulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Maximize and Minimize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
Scheduling Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Functions that Communicate with Users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Writing to the Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Send information to the User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270

9

Data Tables
Working with Data Table Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Get Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
Basic Data Table Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Open a Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Create a New Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Import Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
Set the Current Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Name a Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Save a Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Hide a Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Advanced Data Table Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Accessing Data Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Add Metadata to a Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
Calculations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366

Scripting Guide

15

10 Scripting Platforms
Create, Repeat, and Modify Analyses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
Scripting Analysis Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
Launching Platforms Interactively and Obtaining the Equivalent Script . . . . . . . . . . . . . . . . 373
Launch a Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
Save Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
Make Some Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
Syntax for Platform Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
BY Group Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
Saving BY Group Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Sending Script Commands to a Live Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Conventions for Commands and Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
Sending Several Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
Learning the Messages an Object Responds to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
How to Interpret the Listing from Show Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
Launching Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
Specifying Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
Platform Action Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
Invisible Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
Report Titles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
General Messages for Platform Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
Additional Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
Supercategories in Categorical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
Spline Fits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
Fit Model Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
Fit Model Send Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
DOE Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
Scatterplot Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Process Capability Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Control Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395

11 Display Trees
Create and Use Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
Manipulating Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403

16

Scripting Guide

Introduction to Display Boxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
Display Box Object References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Sending Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
How to Access Built‐in Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
Using the Pick Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Files in Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
Constructing Display Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Updating an Existing Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
Interactive Display Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
Modal and Non‐Modal Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Send Messages to Constructed Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
Build Your Own Displays from Scratch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Construct Display Boxes Containing Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Construct a Custom Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
Journals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
Picture Display Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
Modal Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
Constructing Modal Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
General‐Purpose Modal Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Convert Deprecated Dialog to New Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
Comparison of Dialog and New Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
Constructing Dialogs and Column Dialogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
Scripting the Script Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
Syntax Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478

12 Scripting Graphs
Create and Edit 2-Dimensional Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
Adding Scripts to Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
Ordering Graphics Elements Using JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
Adding a Legend to a Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
Creating New Graphs From Scratch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
Making Changes to Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496

Scripting Guide

17

Graphing Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
Plotting Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
Getting the Properties of a Graphics Frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
Adding a Legend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
Drawing Lines, Arrows, Points, and Shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
Arrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
Markers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Pies and Arcs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Regular Shapes: Circles, Rectangles, and Ovals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
Irregular Shapes: Polygons and Contours . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
Adding text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
Transparency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Fill patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Line types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Drawing With Pixels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Interactive graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
Handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
MouseTrap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
Drag Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
Creating Background Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527

13 Three-Dimensional Scenes
Scripting in Three Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
About JSL 3‐D Scenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
JSL 3‐D Scene Boxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
Setting the Viewing Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
Setting Up a Perspective Scene . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
Setting up an Orthographic Scene . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Changing the View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
The Translate Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
The Rotate Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
The Look At Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541

18

Scripting Guide

The ArcBall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Graphics Primitives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
Primitives Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Controlling the Appearance of Primitives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
Other uses of Begin and End . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
Drawing Spheres, Cylinders, and Disks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
Drawing Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
Using the Matrix Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
Lighting and Normals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
Creating Light Sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
Lighting Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
Normal Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
Shading Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
Material Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
Alpha Blending . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
Fog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
Bézier Curves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566
Using the Mouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569
Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571

14 Extending JMP
External Data Sources, Analytical Tools, and Automation . . . . . . . . . . . . . . . . . . . . . . . . . 573
Real‐Time Data Capture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575
Create a Datafeed Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575
Read in Real‐Time Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576
Manage a Datafeed with Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577
Dynamic Link Libraries (DLLs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581
Using Sockets in JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
Database Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
Working with SAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590
Make a SAS DATA Step . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590
Create SAS DATA Step Code for Formula Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590
SAS Variable Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591

Scripting Guide

19

Get the Values of SAS Macro Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
Connect to a SAS Metadata Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
Sample Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
Working with MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
Installing MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597
Working with R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Installing R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
JMP to R Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
R JSL Scriptable Object Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
Conversion Between JMP Data Types and R Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604
Working with Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605
Parsing XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606
OLE Automation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
Automating JMP through Visual Basic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
Automating JMP through Visual C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616

15 Creating and Sharing Applications
Application Builder and Add-In Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621
Application Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Application Builder Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Design an Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Application Builder Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Red Triangle Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629
Create an Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Edit or Run an Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642
Options for Saving Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642
JMP Add‐Ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 646
Create an Add‐In Using Add‐In Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 646
Edit an Add‐In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
Remove an Add‐In from the Add‐Ins Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
Uninstall an Add‐In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650

20

Scripting Guide

Share an Add‐In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651
Register an Add‐In Using JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652
Create an Add‐In Manually . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652

16 Common Tasks
Getting Started with Sample Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655
Run a Script at Start Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657
Convert Character Dates to Numeric Dates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657
Format Date/Time Values and Subset Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659
Create a Formula Column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660
Extract Values from an Analysis into a Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661
Create an Interactive Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664

A

Compatibility Notes
Changes in Scripting from JMP 11 to JMP 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669
Compatibility Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669
Deprecated JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671

B

Glossary
Terms, Concepts, and Placeholders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673

Index
Scripting Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677

Chapter 1
Learn about JMP
Documentation and Additional Resources
This chapter includes the following information:
•

book conventions

•

JMP documentation

•

JMP Help

•

additional resources, such as the following:
‒ other JMP documentation
‒ tutorials
‒ indexes
‒ Web resources

Figure 1.1 The JMP Help Home Window on Windows

Contents
Formatting Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
JMP Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
JMP Documentation Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
JMP Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Additional Resources for Learning JMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Tutorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Sample Data Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Learn about Statistical and JSL Terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Learn JMP Tips and Tricks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Tooltips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
JMP User Community . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
JMPer Cable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
JMP Books by Users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
The JMP Starter Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Chapter 1
Scripting Guide

Learn about JMP
Formatting Conventions

23

Formatting Conventions
The following conventions help you relate written material to information that you see on
your screen.
•

Sample data table names, column names, pathnames, filenames, file extensions, and
folders appear in Helvetica font.

•

Code appears in Lucida Sans Typewriter font.

•

Code output appears in Lucida Sans Typewriter italic font and is indented farther than
the preceding code.

•

Helvetica bold formatting indicates items that you select to complete a task:

‒ buttons
‒ check boxes
‒ commands
‒ list names that are selectable
‒ menus
‒ options
‒ tab names
‒ text boxes
•

The following items appear in italics:
‒ words or phrases that are important or have definitions specific to JMP
‒ book titles
‒ variables
‒ script output

•

Features that are for JMP Pro only are noted with the JMP Pro icon
of JMP Pro features, visit http://www.jmp.com/software/pro/.

. For an overview

Note: Special information and limitations appear within a Note.
Tip: Helpful information appears within a Tip.

JMP Documentation
JMP offers documentation in various formats, from print books and Portable Document
Format (PDF) to electronic books (e‐books).

24

Learn about JMP
JMP Documentation

Chapter 1
Scripting Guide

•

Open the PDF versions from the Help > Books menu or from the JMP online Help footers.

•

All books are also combined into one PDF file, called JMP Documentation Library, for
convenient searching. Open the JMP Documentation Library PDF file from the Help > Books
menu.

•

e‐books are available at online retailers. Visit http://www.jmp.com/support/downloads/
documentation.shtml for details.

•

You can also purchase printed documentation on the SAS website:
http://support.sas.com/documentation/onlinedoc/jmp/index.html

JMP Documentation Library
The following table describes the purpose and content of each book in the JMP library.
Document Title

Document Purpose

Document Content

Discovering JMP

If you are not familiar
with JMP, start here.

Introduces you to JMP and gets you
started creating and analyzing data.

Using JMP

Learn about JMP data
tables and how to
perform basic
operations.

Covers general JMP concepts and
features that span across all of JMP,
including importing data, modifying
columns properties, sorting data, and
connecting to SAS.

Basic Analysis

Perform basic analysis
using this document.

Describes these Analyze menu platforms:
•

Distribution

•

Fit Y by X

•

Matched Pairs

•

Tabulate

How to approximate sampling
distributions using bootstrapping and
modeling utilities are also included.

Chapter 1
Scripting Guide

Learn about JMP
JMP Documentation

Document Title

Document Purpose

Document Content

Essential Graphing

Find the ideal graph
for your data.

Describes these Graph menu platforms:
•

Graph Builder

•

Overlay Plot

•

Scatterplot 3D

•

Contour Plot

•

Bubble Plot

•

Parallel Plot

•

Cell Plot

•

Treemap

•

Scatterplot Matrix

•

Ternary Plot

•

Chart

The book also covers how to create
background and custom maps.
Profilers

Learn how to use
interactive profiling
tools, which enable you
to view cross‐sections
of any response
surface.

Covers all profilers listed in the Graph
menu. Analyzing noise factors is
included along with running simulations
using random inputs.

Design of
Experiments Guide

Learn how to design
experiments and
determine appropriate
sample sizes.

Covers all topics in the DOE menu and
the Screening menu item in the Analyze >
Modeling menu.

25

26

Learn about JMP
JMP Documentation

Chapter 1
Scripting Guide

Document Title

Document Purpose

Document Content

Fitting Linear Models

Learn about Fit Model
platform and many of
its personalities.

Describes these personalities, all
available within the Analyze menu Fit
Model platform:

Specialized Models

Learn about additional
modeling techniques.

•

Standard Least Squares

•

Stepwise

•

Generalized Regression

•

Mixed Model

•

MANOVA

•

Loglinear Variance

•

Nominal Logistic

•

Ordinal Logistic

•

Generalized Linear Model

Describes these Analyze > Modeling
menu platforms:
•

Partition

•

Neural

•

Model Comparison

•

Nonlinear

•

Gaussian Process

•

Time Series

•

Response Screening

The Screening platform in the Analyze >
Modeling menu is described in Design of
Experiments Guide.
Multivariate
Methods

Read about techniques
for analyzing several
variables
simultaneously.

Describes these Analyze > Multivariate
Methods menu platforms:
•

Multivariate

•

Cluster

•

Principal Components

•

Discriminant

•

Partial Least Squares

Chapter 1
Scripting Guide

Learn about JMP
JMP Documentation

Document Title

Document Purpose

Document Content

Quality and Process
Methods

Read about tools for
evaluating and
improving processes.

Describes these Analyze > Quality and
Process menu platforms:

Reliability and
Survival Methods

Consumer Research

Learn to evaluate and
improve reliability in a
product or system and
analyze survival data
for people and
products.

Learn about methods
for studying consumer
preferences and using
that insight to create
better products and
services.

•

Control Chart Builder and individual
control charts

•

Measurement Systems Analysis

•

Variability / Attribute Gauge Charts

•

Process Capability

•

Pareto Plot

•

Diagram

Describes these Analyze > Reliability and
Survival menu platforms:
•

Life Distribution

•

Fit Life by X

•

Recurrence Analysis

•

Degradation and Destructive
Degradation

•

Reliability Forecast

•

Reliability Growth

•

Reliability Block Diagram

•

Survival

•

Fit Parametric Survival

•

Fit Proportional Hazards

Describes these Analyze > Consumer
Research menu platforms:
•

Categorical

•

Multiple Correspondence Analysis

•

Factor Analysis

•

Choice

•

Uplift

•

Item Analysis

27

28

Learn about JMP
Additional Resources for Learning JMP

Chapter 1
Scripting Guide

Document Title

Document Purpose

Document Content

Scripting Guide

Learn about taking
advantage of the
powerful JMP
Scripting Language
(JSL).

Covers a variety of topics, such as writing
and debugging scripts, manipulating
data tables, constructing display boxes,
and creating JMP applications.

JSL Syntax Reference

Read about many JSL
functions on functions
and their arguments,
and messages that you
send to objects and
display boxes.

Includes syntax, examples, and notes for
JSL commands.

Note: The Books menu also contains two reference cards that can be printed: The Menu Card
describes JMP menus, and the Quick Reference describes JMP keyboard shortcuts.

JMP Help
JMP Help is an abbreviated version of the documentation library that provides targeted
information. You can open JMP Help in several ways:
•

On Windows, press the F1 key to open the Help system window.

•

Get help on a specific part of a data table or report window. Select the Help tool
from
the Tools menu and then click anywhere in a data table or report window to see the Help
for that area.

•

Within a JMP window, click the Help button.

•

Search and view JMP Help on Windows using the Help > Help Contents, Search Help, and
Help Index options. On Mac, select Help > JMP Help.

•

Search the Help at http://jmp.com/support/help/ (English only).

Additional Resources for Learning JMP
In addition to JMP documentation and JMP Help, you can also learn about JMP using the
following resources:
•

Tutorials (see “Tutorials” on page 29)

•

Sample data (see “Sample Data Tables” on page 29)

•

Indexes (see “Learn about Statistical and JSL Terms” on page 29)

Chapter 1
Scripting Guide

Learn about JMP
Additional Resources for Learning JMP

•

Tip of the Day (see “Learn JMP Tips and Tricks” on page 30)

•

Web resources (see “JMP User Community” on page 30)

•

JMPer Cable technical publication (see “JMPer Cable” on page 30)

•

Books about JMP (see “JMP Books by Users” on page 31)

•

JMP Starter (see “The JMP Starter Window” on page 31)

29

Tutorials
You can access JMP tutorials by selecting Help > Tutorials. The first item on the Tutorials menu
is Tutorials Directory. This opens a new window with all the tutorials grouped by category.
If you are not familiar with JMP, then start with the Beginners Tutorial. It steps you through the
JMP interface and explains the basics of using JMP.
The rest of the tutorials help you with specific aspects of JMP, such as creating a pie chart,
using Graph Builder, and so on.

Sample Data Tables
All of the examples in the JMP documentation suite use sample data. Select Help > Sample
Data Library to do the following actions to open the sample data directory.
To view an alphabetized list of sample data tables or view sample data within categories,
select Help > Sample Data.
Sample data tables are installed in the following directory:
On Windows: C:\Program Files\SAS\JMP\\Samples\Data
On Macintosh: \Library\Application Support\JMP\\Samples\Data
In JMP Pro, sample data is installed in the JMPPRO (rather than JMP) directory. In JMP
Shrinkwrap, sample data is installed in the JMPSW directory.

Learn about Statistical and JSL Terms
The Help menu contains the following indexes:
Statistics Index Provides definitions of statistical terms.

Lets you search for information about JSL functions, objects, and display
boxes. You can also edit and run sample scripts from the Scripting Index.

Scripting Index

30

Learn about JMP
Additional Resources for Learning JMP

Chapter 1
Scripting Guide

Learn JMP Tips and Tricks
When you first start JMP, you see the Tip of the Day window. This window provides tips for
using JMP.
To turn off the Tip of the Day, clear the Show tips at startup check box. To view it again, select
Help > Tip of the Day. Or, you can turn it off using the Preferences window. See the Using JMP
book for details.

Tooltips
JMP provides descriptive tooltips when you place your cursor over items, such as the
following:
•

Menu or toolbar options

•

Labels in graphs

•

Text results in the report window (move your cursor in a circle to reveal)

•

Files or windows in the Home Window

•

Code in the Script Editor

Tip: You can hide tooltips in the JMP Preferences. Select File > Preferences > General (or JMP
> Preferences > General on Macintosh) and then deselect Show menu tips.

JMP User Community
The JMP User Community provides a range of options to help you learn more about JMP and
connect with other JMP users. The learning library of one‐page guides, tutorials, and demos is
a good place to start. And you can continue your education by registering for a variety of JMP
training courses.
Other resources include a discussion forum, sample data and script file exchange, webcasts,
and social networking groups.
To access JMP resources on the website, select Help > JMP User Community.

JMPer Cable
The JMPer Cable is a yearly technical publication targeted to users of JMP. The JMPer Cable is
available on the JMP website:
http://www.jmp.com/about/newsletters/jmpercable/

Chapter 1
Scripting Guide

Learn about JMP
Additional Resources for Learning JMP

31

JMP Books by Users
Additional books about using JMP that are written by JMP users are available on the JMP
website:
http://www.jmp.com/support/books.shtml

The JMP Starter Window
The JMP Starter window is a good place to begin if you are not familiar with JMP or data
analysis. Options are categorized and described, and you launch them by clicking a button.
The JMP Starter window covers many of the options found in the Analyze, Graph, Tables, and
File menus.
•

To open the JMP Starter window, select View (Window on the Macintosh) > JMP Starter.

•

To display the JMP Starter automatically when you open JMP on Windows, select File >
Preferences > General, and then select JMP Starter from the Initial JMP Window list. On
Macintosh, select JMP > Preferences > Initial JMP Starter Window.

32

Learn about JMP
Additional Resources for Learning JMP

Chapter 1
Scripting Guide

Chapter 2
Introduction
Welcome to the JMP Scripting Language
The JMP Scripting Language, or JSL, lets you write scripts to recreate results in JMP. Power
users often develop scripts to extend JMP’s functionality and automate a regularly scheduled
analysis in production settings. If you do not want to learn JSL, JMP can write the scripts for
you.
JSL is used to perform many actions:
•

implements column formulas

•

launches platforms

•

interactively modifies platforms

•

creates graphics

Contents
What JSL Can Do for You. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Help with Learning JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
The Scripting Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
The Scripting Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Let JMP Teach You JSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Basic JSL Syntax. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

Chapter 2
Scripting Guide

Introduction
What JSL Can Do for You

35

What JSL Can Do for You
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 (or script editor), in
a data table, or in an analysis report. You can then modify the script as needed for future
projects. When you are finished with your work, you can then save a script to reproduce your
final results.
Here are some examples where JSL scripts can be helpful:
•

Suppose you need to describe an analysis process in detail, from beginning to end. An
example is to create an audit trail for a governing agency, or for peers reviewing your
journal article.

•

Suppose you have a set of analysis steps that should be followed routinely by your lab
technicians.

•

Suppose you fit the same model to new data every day, and the steps are always the same.

You can use JMP interactively as usual, save scripts to reproduce your work, and in the future
run those scripts to reproduce your results.
There are a few things that JSL is not designed to do:
•

JMP cannot record scripts while you are working. Though script‐recording is a useful
feature in some other scripting languages, it is less important for software like JMP, where
the results are what matter. You cannot use script‐recording to observe how a sequence of
interactive steps is performed.

•

JSL is not an alternative command‐line interface for using the program.

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

The Scripting Guide
The Scripting Guide book begins with basic information (such as terminology and syntax) for
JMP users who are not familiar with the scripting language. The book progresses to more
advanced information.
Chapters 2 through 4

Includes information about learning JSL, producing
basic scripts, and introduces you to the JSL scripting
environment.

36

Introduction
Help with Learning JSL

Chapter 2
Scripting Guide

Chapters 5 through 8

Introduces the building blocks of the language;
working with basic data types, such as numbers and
strings; writings lists, matrices, and associate arrays;
namespaces; and the fundamentals of programming in
JSL.

Chapters 9 through 13

Covers using JSL with objects in JMP, such as data
tables, platforms, windows, and graphics.

Chapter 14

Describes how to write scripts that work with external
programs, such as SAS, R, and Excel.

Chapter 15

Introduces creating JMP applications in Application
Builder, a drag‐and‐drop environment for visually
designing windows with buttons, lists, graphs, and
other objects. The chapter also describes how to use
Add‐In Builder to compile scripts into one easily shared
file.

Chapter 16

Contains a collection of recipes, or script examples, that
you can copy and modify for your own use.

Appendices A and B

Provides information about compatibility issues with
the previous version of JMP and defines JSL concepts
and terminology.

The Scripting Index
The Scripting Index on the Help menu provides a brief description and the syntax for JSL
functions, objects, and display boxes. Each entry includes an example that you can run and
modify to test your own code. And an embedded log window lets you see messages as
examples are run.
The Scripting Index window includes the following buttons:
Click the Search button to begin the search.
Click the Clear button to clear the search text box to begin a new search.
Click the Settings button to set search types and parameters.
Several types of searches are available from the Settings button:
Partial Match returns all entries that contain at least a part of the “string” for example, a

search for “leas” will return messages such as “Release Zoom” and “Partial Least Squares”.
This option is the default search type.

Chapter 2
Scripting Guide

Introduction
Help with Learning JSL

37

Exact Phrase returns entries that contain the exact string, for example, a search for “text” will

return all elements that contain the “text” string.
returns entries that contain either or both strings, for example, a search for “t test”
will return all elements that contain either or both of the search strings, “Pat Test”,
“Shortest Edit Script” and “Paired t test”.

All Terms

Any Term returns entries that contain either of the search strings, for example, a search for

“text string” returns “Context Box”, “Drag Text”, and “Is String”.
allows you to use the wildcard (*) and period (.) in the search box, for
example, searching for “get *name” returns messages such as “Get Name Info” and “Get
Namespace”. Searching for “get.*name” returns items such as “Get Color Theme Names”,
“Get Name Info”, and “Get Effect Names”.

Regular Expression

Several search parameters are also available from the Settings button:
All Fields specifies that JMP search all fields in the index for the search string.
Titles Only

specifies that JMP search only index titles for the search string.

Examples Only

specifies that JMP search only index examples for the search string.

Without Examples specifies that JMP exclude examples from the search.

Click an item’s Topic Help button to read more about the item in JMP’s online Help system.

Let JMP Teach You JSL
The best JSL writer is JMP. You can work in JMP interactively and then save the results as a
script to reuse later. With simple modifications, your script can serve as a template for
speeding up routine tasks.
Because JSL is a very flexible language, you can reach your goals in many different ways. Here
is an example. 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 that you write have to be just as complete and detailed? Not at all. You usually need to
specify only those details that you would select in the graphical user interface (GUI). For
example, if you open Big Class.jmp from the sample data folder and want to launch
Distribution for height, weight, and sex, the following script is all that is necessary:
Distribution( Y( :height, :weight, :sex ) );

Suppose you run the Distribution platform in the GUI and then select Script > Save Script to
Script Window from the red triangle menu for the report. The following script appears:
Distribution(
Nominal Distribution( Column( :sex ) ),
Continuous Distribution( Column( :height ) ),
Continuous Distribution( Column( :weight ) )

38

Introduction
Terminology

Chapter 2
Scripting Guide

);

Both scripts give the same result.
Feel free to experiment with JSL. If you think something ought to be possible, it probably is.
Give it a try, and see what happens.

Terminology
Before you begin creating scripts, you should become familiar with basic JSL terms used
throughout this book.
Operators and Functions
An operator is one‐ or two‐character symbol (such as + or =) for common arithmetic actions.
A function is a command that might contain additional information for the function to use.
Certain JSL functions work the same as operators but provide access to more complex actions.
For example, the following two lines are equivalent:
2 + 3;
Add( 2, 3 );

The first line uses the + operator. The second line uses the Add() function equivalent.
Although all JSL operators have function equivalents, not all functions have operator
equivalents. For example, Sqrt(a) can be represented only by the Sqrt() function.
Note: In previous versions of JMP and its documentation, the terms operators and functions
were used interchangeably. Now each term has a specific meaning.
Objects and Messages
An object is a dynamic entity in JMP, such as a data table, a data column, a platform results
window, a graph, and so on. Most objects can receive messages that instruct the object to
perform some action on itself.
A message is a JSL expression that is directed to an object. That object knows how to evaluate
the message. In the following example, dt is the data table object. << indicates that a message
follows. In the following example, the message tells JMP to create a summary table with the
specified variables.
dt << Summary( Group( :age ), Mean( :height ) )

In this expression, dt is the name of a variable that contains a reference to a data table. You
could use any name for this variable. This book commonly uses dt to represent data table

Chapter 2
Scripting Guide

Introduction
Terminology

39

references. Here are some of the more common names used in this book to represent
references to certain objects:
Abbreviation

Object

dt

data table

col

column in a data table

colname

the name of a column in a data table

obj

an object

db

display box

These variables are not pre‐assigned references. Each one must be assigned prior to its use. In
the following example, the global variable named A is assigned the value “Hello, World”.
When the Show( A ) command is processed, the result is the value of A.
A = "Hello, World";
Show( A );
A = "Hello, World";

Arguments and Parameters
An argument is additional information that you can provide to a function or message. For
example, in Root(25), 25 is an argument to the Root() function. Root() acts on the argument
that you provide and returns the result: 5.
Programming and scripting books commonly talk about parameters as well. A parameter is a
description of the argument that a function accepts. For example, the general specification for
Root() might be Root( number ), where number is the parameter.
Parameter and argument express two perspectives of the same concept: information that a
function needs.
For simplicity in this book, we use the word argument in both cases.
A named argument is an optional argument that you select from a predetermined set and
explicitly define. For example, title("My Line Graph") in the Graph Box() function is a
named argument because the title is explicitly defined as such.
Graph Box( title("My Line Graph"),
Frame Size( 300, 500 ),
Marker( Marker State( 3 ), [11 44 77], [75 25 50] );
Pen Color( "Blue" );
Line( [10 30 70], [88 22 44] ));

40

Introduction
Terminology

Chapter 2
Scripting Guide

Note that the Frame Size() arguments 300 and 500 are not named. The position of these
arguments implies meaning; the first argument is always the width, the second argument is
always the height.
Optional Arguments
Functions and messages require certain arguments, and other arguments are optional. You
can include them, but you do not have to. In specifications, optional arguments are enclosed in
angle brackets. For example:
Root( x,  )

The x argument is required. The n argument is optional.
Optional arguments often have a default value. For example, for Root(), the default value of n
is 2:
Code

Output

Explanation

Root( 25 )

5

Returns the square root of 25.

Root( 25, 2 )

5

Returns the square root of 25.

Root( 25, 3 )

2.92401773821287

Returns the cube root of 25.

Expressions
An expression is a section of JSL code that accomplishes a task. JSL expressions hold data,
manipulate data, and send commands to objects. For example, the following expression opens
the Big Class.jmp sample data table and creates a Bivariate graph:
Open( "$SAMPLE_DATA/Big Class.JMP" );
Bivariate( Y( :weight ), X( :height ) );

Or and the Vertical Bar Symbol
A single vertical bar (|) represents a logical OR. For brevity, | represents the word or when
referring to alternative values.
For example, a pathname can be either absolute or relative. When you see an argument such
as absolute|relative, this means that you enter either one of the following two options:
•

absolute indicates an absolute pathname.

•

relative indicates a relative pathname.

More than two options can also be strung together with a vertical bar in this way.

Chapter 2
Scripting Guide

Introduction
Basic JSL Syntax

41

Script Formatting
Whitespace characters (such as spaces, tabs, and newlines) and capitalization are ignored in
JSL. This means that the following two expressions are equivalent:
// Expression 1
sum=0; for(i=1,i<=10,i++,sum+=i;show(i,sum))
// Expression 2
Sum = 0;
For( i = 1, i <= 10, i++,
Sum += i;
Show( i, Sum );
);

You can format your script in any way that you like. However, the script editor can also format
your script for you. This book uses the script editor’s default formatting for capitalization,
spaces, returns, tabs, and so on. See “Using the Script Editor” on page 55 in the “Scripting
Tools” chapter for details about using the script editor.
Note: The only white space exception is two‐character operators (such as <= or ++). The
operators cannot be separated by a space.

Basic JSL Syntax
A JSL script is a series of expressions. Each expression is a section of JSL code that
accomplishes a task. JSL expressions hold data, manipulate data, and send commands to
objects.
Many expressions are nested message names, with message contents enclosed in parentheses:
Message Name ( argument 1, argument 2, ... )

The meaning of JSL names depends on the context. The same name might mean one thing in a
data table context and something entirely different in a function context. See “Rules for Name
Resolution” on page 97 in the “JSL Building Blocks” chapter for more information.
Almost anything that follows certain punctuation rules, such as matching parentheses, is a
valid JSL expression. For example:
New Window( "A Window",
<< modal,
Text box( "Hello, World" ),
Text Box( "-----" ),
ButtonBox( "OK" )
);

42

Introduction
Basic JSL Syntax

Chapter 2
Scripting Guide

Notice the following:
•

Names can have embedded spaces. See “Names” on page 88 in the “JSL Building Blocks”
chapter for more information.

•

Message contents are enclosed in parentheses, which must be balanced. See “Parentheses”
on page 85 in the “JSL Building Blocks” chapter.

•

Items are separated by commas. See “Commas” on page 85 in the “JSL Building Blocks”
chapter.

•

JSL is not case sensitive; you can type “text box();” or “Text Box()”.

•

Messages are commonly nested inside other messages.

Chapter 3
Getting Started
Let JMP Write Your Scripts
You often have to produce the same reports for the same data on a regular basis. This chapter
shows you how to let JMP write scripts for common tasks like importing text data, opening
Excel files, and producing reports. A final tutorial shows you how to put it all together into a
single script to open an Excel file and produce three reports automatically.
This book is written for users who are familiar with JMP but might not be familiar with JSL.
For information about performing common tasks, refer to the Using JMP book. The Discovering
JMP book is also a good resource for learning basic concepts and understanding the JMP
workflow.

Contents
Capturing a Script for an Analysis Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Capturing a Script for a Data Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Capturing a Script to Import a File. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Gluing Scripts Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

Chapter 3
Scripting Guide

Getting Started
Capturing a Script for an Analysis Report

45

Capturing a Script for an Analysis Report
The basic steps for capturing a script to reproduce an analysis are as follows:
1. Launch a platform, such as Distribution.
2. Make any changes or additions that you need. For example, add tests and other graphs.
3. Capture the script to recreate your results.
You can save the script in the data table, so that if you send the data table to others, they can
run your script and duplicate your reports.
Example
Follow these steps to produce a distribution report, capture the script to reproduce it, and save
it to the data table.
Note: The data tables that you use in examples are located in JMP’s Samples/Data folder.
1. Select Help > Sample Data Library and open the Companies.jmp.
2. Select Analyze > Distribution to open the Distribution launch window.
3. Select Profits ($M) in the Select Columns box and click the Y, Columns button.
4. Click OK.
The Distribution report window appears.
5. From the red triangle menu next to Distributions, select Stack to make your report
horizontal.
6. From the red triangle menu next to Profits ($M), deselect Outlier Box Plot to turn the
option off.
7. From the red triangle menu next to Profits ($M), select Test Mean.
The Test Mean window appears.
8. Type 500 in the Specify Hypothesized Mean box.
9. Click OK.
The test for the mean is added to the report window.
Now you have your customized report.

46

Getting Started
Capturing a Script for a Data Table

Chapter 3
Scripting Guide

Figure 3.1 Customized Distribution Report

10. From the red triangle menu next to Distributions, select Script > Save Script to Data Table.
Your data table now has a script named Distribution saved to it. From the red triangle
menu for the script, select Edit to see the script.
Figure 3.2 Distribution Script Saved to the Data Table

11. To run the script and reproduce your final report exactly, select Run Script from the red
triangle menu for the script.

Capturing a Script for a Data Table
The basic steps for capturing a script to reproduce a data table are as follows:
1. Open the data table.
2. Make any changes that you need. For example, add a script, correct values, add new
columns.

Chapter 3
Scripting Guide

Getting Started
Capturing a Script to Import a File

47

3. Capture the script to recreate your data table.
Example
Use the data table from the previous example, where you saved a script to it.
1. In the data table, select the red triangle next to the data table’s name.
2. Select Copy Table Script.
Figure 3.3 Copy the Table Script

3. Open a script window by selecting File > New > Script.
4. Select Edit > Paste.
You now have a script that duplicates your data table. You can save this script and run it at
any time to recreate your data table, with all its scripts attached.

Capturing a Script to Import a File
To capture a script that imports a file, you open the file in JMP. JMP automatically records the
steps that occurred when you opened the file.
Import a Text File
1. Select File > Open.
The Open Data File window appears.
2. Select Text Files from the list next to File name.
3. In the Open as section, select Data, using best guess.
JMP formats the data based on tabs, commas, white space, and other characters in the text
file.

48

Getting Started
Gluing Scripts Together

Chapter 3
Scripting Guide

4. Browse to select the file, and then select Open.
The file is opened as a data table. The data table includes a script named Source. This JSL
script imports your text file with the text import rules that you used.
5. From the red triangle menu for Source, select Edit.
You can copy this script, paste it into a new script window, and save it. Then you can run
this script later to reimport the text file.
Tip: The import script is an Open() expression that specifies the text file and the import
options to correctly import the file into JMP. The first part of this expression is the pathname to
the specific file that you imported. If you save this script and want to run it a different place,
you might need to edit the pathname so that it points to the text file. Pathnames are discussed
in greater detail in “Path Variables” on page 126 in the “Types of Data” chapter.

Gluing Scripts Together
Suppose new data is saved out to an Excel file once a week, and you need to produce the same
reports every week. You could open the file and perform the same steps every week. However,
creating a script that imports the new Excel file into JMP and runs all analyses automatically is
more efficient. The following example shows you how to set up your script and run it each
week.
Import the Microsoft Excel File
1. Open a new script window (File > New > Script).
2. In your script window, enter the Open() expression to open the Solubil.xls sample import
data file. The file is located in JMP’s Samples/Import Data folder.
Open( "$SAMPLE_IMPORT_DATA/Solubil.xls" );

Be sure to put the semicolon at the end of this expression, because you will add more
expressions. The semicolon glues expressions together.
3. Run your script to import the Excel file by selecting Edit > Run Script.
The Excel file opens as a data table.
Note: You can specify an absolute or relative path to the file rather than using a path variable.
For relative links, the script and file being opened must be in the same relative location each
time you run the script. With absolute links, make sure that other users running the script
have access to the file’s location. See “Path Variables” on page 126 in the “Types of Data”
chapter for more information about using pathnames.

Chapter 3
Scripting Guide

Getting Started
Gluing Scripts Together

49

Run Your Reports and Capture Their Scripts
You have three reports to produce: a distribution report, a 3D scatterplot, and a multivariate
report. Perform each one using the GUI, and add its script to the script window.
1. With your new data table open, select Analyze > Distribution.
2. Select all the columns except Labels and click Y, Columns.
3. Click OK.
4. Hold down CTRL and select Histogram Options > Show Counts from the red triangle
menu for eth.
Bar counts are added to all six histograms.
5. In the Distribution window, select Script > Copy Script from the red triangle menu next to
Distributions.
6. Place your cursor in the script window a line or two after your Open() expression and
select Edit > Paste.
7. Type a semicolon after the last close parenthesis.
8. Select Graph > Scatterplot 3D.
9. Select all the columns except Labels and click Y, Columns.
10. Click OK.
11. Copy and paste the script for Scatterplot 3D into the script window just like you did for
your Distribution report. Be sure to add the semicolon at the end.
12. Select Analyze > Multivariate Methods > Multivariate.
13. Select all the columns except Labels and click Y, Columns.
14. Click OK.
15. Copy and paste the script for Multivariate into the script window just like you did for
Distributions and Scatterplot 3D.

50

Getting Started
Gluing Scripts Together

Chapter 3
Scripting Guide

Figure 3.4 The Completed Script

Save the Script
You now have a script that reproduces all of the steps that you performed manually. Save the
script, and close your data table and all its report windows.
1. In the script window that contains your script, select File > Save or File > Save As.
2. Specify a filename (for example, Weekly Report).
3. Click Save.
Run the Script
As long as your weekly updated Excel file is saved in the same place and contains the same
columns, you can run your script and automatically produce all your reports.
1. Open the script that you saved.
2. Select Edit > Run Script.
Your Excel file is opened in JMP, and all three of your reports appear.
You can send this script to others. As long as they have access to the same Excel file in the
same location, they can also run the script in JMP and see your reports.
Advanced Note: Auto‐Submit
If you want a particular script to always be executed instead of opened into the script window,
put the following command on the first line of the script:
//!

If this is not the very first line, with nothing else on the same line, this command does nothing.

Chapter 3
Scripting Guide

Getting Started
Gluing Scripts Together

You can override this command when opening the file.
1. Select File > Open.
2. Hold the CTRL key while you select the JSL file and click Open.
The script opens into a script window instead of being executed.
The command is also ignored when you right‐click the file in the Home Window and select
Edit Script.

51

52

Getting Started
Gluing Scripts Together

Chapter 3
Scripting Guide

Chapter 4
Scripting Tools
Using the Script Editor, Log Window, Debugger and Profiler
JMP provides several programming tools for script writers. The script editor supports syntax
coloring, autocompletes functions as you type, highlights matching braces, allows for code
folding, and has additional features to help you develop scripts more quickly. Error messages
and output are shown in the log window, which can be displayed inside the script editor. The
JMP Scripting Language (JSL) Debugger and Profiler can help you troubleshoot your scripts.
Figure 4.1 Script Editor with Embedded Log and the Debugger

Contents
Using the Script Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Run a Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Stop a Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Edit a Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Color Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Auto Complete Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Tooltips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Split a Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Match Parentheses, Brackets, and Braces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Select a Rectangular Block of Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Select Fragmented Text. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Drag and Drop Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Find and Replace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Automatic Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Add Code Folding Markers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Advanced Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Set Preferences for the Script Editor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Working with the Log. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Show the Log in the Script Window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Save the Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Debug or Profile Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Debugger and Profiler Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Work with Breakpoints. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
View Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Work with Watches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Modify Preferences in Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Persistent Debugger Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Examples of Debugging and Profiling Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

Chapter 4
Scripting Guide

Scripting Tools
Using the Script Editor

55

Using the Script Editor
The script editor provides a friendly environment for writing and reading JSL scripts.
Figure 4.2 shows basic features such as syntax coloring, inline commenting, and automatic
formatting. Other common programming options are described later in this section.
Script editor features are also available in the log window and anywhere else that you can edit
or write a script (for example, in the Scripting Index or Application Builder).
Figure 4.2 The Script Editor

Run a Script
To run an entire script, select Edit > Run Script.
To run specific lines in a script, select those lines and then select Edit > Run Script.
To run specific lines that are not adjacent, hold down the Control key, select the lines, and then
select Edit > Run Script.
On Windows, you can also click in a line or select several lines and press ENTER on your
numeric keypad.
Run the script automatically when you open it by using one of the following methods:
•

Type //! on the first line.

•

Include Run JSL(1) in the Open() statement:

56

Scripting Tools
Using the Script Editor

Chapter 4
Scripting Guide

Open( "$SAMPLE_SCRIPTS/scoping.jsl", Run JSL( 1 ) );

Stop a Script
To stop the script, press ESC on Windows (or COMMAND‐PERIOD on Macintosh). You can
also select Edit > Stop Script. On Macintosh, Edit > Stop Script is available only when the
script is running.

Edit a Script
To edit a script on Windows, press the Insert key. You can then type directly over (overwrite)
any existing JSL code. Note that this feature is not available on Macintosh.

Color Coding
JMP applies the following colors in the script window:
•

black for text, identifiers (JSL functions), braces, and user macros

•

white for the script editor background

•

gray for the Debugger background, disabled background, and guides

•

green for comments

•

purple for strings

•

teal blue for numbers

•

dark blue for operator symbols, the first keyword, and JSL objects

•

medium blue for operator names, second and third keywords, and macros

•

red for unknown objects

Customize colors in the preferences. See “Set Preferences for the Script Editor” on page 63.

Auto Complete Functions
If you do not remember the exact name of a function, use auto completion to see a list of
functions that match what you have typed so far. Type part of the name, and then press
CTRL‐SPACE on Windows (OPTION‐ESC on Macintosh).
Suppose that you want to clear your JSL variables, but do not remember the command. You
can type clear and then press CTRL‐SPACE, to see a list of possible clear commands. Select
the command that you want to insert.

Chapter 4
Scripting Guide

Scripting Tools
Using the Script Editor

57

Figure 4.3 Autocomplete Example

Tooltips
If you are using a function and do not remember the syntax or need more information about
it, place the cursor over it to see a brief explanation. This works only with JSL function names,
not platform commands, messages, or user‐created functions. JSL function names are colored
blue in the script editor.
The tooltip shows the syntax, arguments, and a brief explanation of the function (Figure 4.4).
The tip also appears in the script editor window status bar.
Figure 4.4 Tooltip for a JSL Function

After running a script, you can also place the cursor over variable names to see their current
value. To turn off variable tooltips, deselect Preferences > Script Editor > Show Variable Value
Tips.
To turn off function tooltips, deselect Preferences > Script Editor > Show Operator Tips.
Example of a Tooltip for a JSL Variable
1. Enter and run the following line in a script window:
my_variable = 8;

2. Hover over the variable name after you run the line.
A tooltip shows the name of the variable and its value: 8.
3. Enter and run the following line:
my_variable = "eight";

4. Hover over the variable name after you run the line.
A tooltip shows the name of the variable and its value: “eight”.

58

Scripting Tools
Using the Script Editor

Chapter 4
Scripting Guide

Split a Window
You can split the Script Editor window into two vertical or horizontal windows. This feature
allows you to independently scroll through your code in two different places and edit the
contents in both. When you make a change in one window, the change is immediately
reflected in the other window.
•

To split an open Script Editor window, right‐click in the window and select Split >
Horizontal or Vertical.

•

To revert back to a single window, right‐click and select Remove Split.

Figure 4.5 Example of Splitting a Window Horizontally

Chapter 4
Scripting Guide

Scripting Tools
Using the Script Editor

59

Match Parentheses, Brackets, and Braces
The script editor helps you match fences (or parentheses, square brackets, and curly braces) in
the following ways:
•

The matching closing fence is added when you type an opening fence.

•

When you place your cursor next to either an opening or closing fence, the fence and its
match are highlighted in blue. If the fence does not have a match, it is highlighted in red.

•

If you double‐click a fence, everything between the matching fence is selected (including
the fences).

•

If you put your cursor within an expression and press CTRL‐] on Windows
(COMMAND‐B on Macintosh), the entire expression is selected. Fences that enclose the
expression are included. Repeat this process to highlight the next‐higher expression.
Figure 4.6 shows an example.

Figure 4.6 Each Step in Matching Fences

When you type an opening brace, JMP adds the closing brace. Enter code between the braces,
type the closing brace, and then your cursor automatically moves after the closing brace that
JMP added. This prevents you from accidentally adding an unnecessary closing brace.
You can turn on and off the auto completion of braces in the JMP preferences. See “Set
Preferences for the Script Editor” on page 63 for details.

Select a Rectangular Block of Text
To select a rectangular block of text, hold down the ALT key and drag your cursor from the
starting point to the end of the block. You can either copy or cut the text enclosed in the block.
Suppose that you want to the select all of the following code except for the comment marks.

60

Scripting Tools
Using the Script Editor

Chapter 4
Scripting Guide

// Y( :Y ),
// X( :X ),

Select a rectangular portion beginning with Y. When you paste, you get the following code:
Y( :Y ),
X( :X ),

The rectangular selection inserts returns where needed to maintain the structure of the text.
Select Get Menu Item State on both lines in the following example.
bb << Get Menu Item State(1),
bb << Get Menu Item State(2),

When you paste, a return is inserted at the end of each line.
Get Menu Item State
Get Menu Item State

Select Fragmented Text
To select text that is not contiguous, hold down the Ctrl key on Windows or Command key on
Mac and drag your cursor over the text. Continue this action for any other text that you want
to select. You can then copy and paste your selection into a new script or you can run the
selected text. Text will be pasted or run in the order it was selected.

Drag and Drop Text
You can drag and drop text within a script editor window or between windows or from a data
table into a script editor window. On Windows, pressing CTRL before dragging and dropping
copies the text. On Macintosh, the text is copied by default.
Drag and drop text as follows:
•

Select a row or column, pause, and then drop it into the script editor window.

•

Double‐click text in a text field and then drop it into the script editor window. Examples
are text in a data table cell and any other selectable text.

On Windows, you can also drag and drop text into a minimized window.
1. Drag the text over the Home Window button

in the lower right corner of the window.

The Home Window appears.
2. In the Home Window list, drag the text over the destination window.
That window appears.
3. Drop the text where you want it.

Chapter 4
Scripting Guide

Scripting Tools
Using the Script Editor

61

Find and Replace
Many find and replace options are available in the script editor, including the support of
regular expressions. For example, searching with the following regular expression:
get.*name

returns messages such as “Get Button Name”, and “GetFontName”.
Basic regular expressions such as ^ and $ (which match the start of line and end of line) and \n
(which matches a carriage return) are also supported.
See the Using JMP book for details about the Search options.

Automatic Formatting
The script editor can format a script for easier reading. Any generated script (for example, by
saving a platform script) is automatically formatted with tabs and returns in appropriate
places.
You can also reformat individual scripts that are difficult to read (for example, scripts in which
all commands are strung together with no whitespace characters). From the Edit menu, select
Reformat Script.
Tip: This command alerts you if your script is badly formed (for example, if your parentheses
are not matched).

Add Code Folding Markers
You can add code folding markers that show the beginning and the end of the code block,
allowing you to collapse and expand code inside stand‐alone functions.
To turn on this feature, select JSL code folding in the Script Editor preferences. Then you can
expand and collapse blocks of code by right‐clicking on a script and selecting Advanced >
Expand All or Collapse All.
After you select this preference, Function and Expr expressions are foldable. See “Add More
Folding Keywords” on page 62 for details about adding folding markers to other expressions.

62

Scripting Tools
Using the Script Editor

Chapter 4
Scripting Guide

Figure 4.7 Code Folding Markers Shown in a Script

By default, code does not remain collapsed after you save the script and restart JMP. To save
the state of the folded code, select Save and restore document state information in the Script
Editor preferences.
Add More Folding Keywords
Custom code folding is supported for other stand‐alone functions as shown in the following
example:
{"If", "For", "For Each Row", "While", "Try", "New Window", "V List Box",
"H List Box"}

JMP supports multiple keyword lists. A system administrator can define a set of keywords in
jmpKeywords.jsl and save the script in C:\ProgramData\SAS\JMP\ or designated directory
listed below. You save your version of jmpKeywords.jsl in your C:\Users\\Documents\
folder. JMP merges all keyword lists from the designated directories.
Note: Path names in this section refer to the JMP folder. In JMP Pro, the folder is named
“JMPPro”. In JMP Shrinkwrap, the folder is named “JMPSW”.
On Windows, the following directories are examined in the order listed:
•

C:\ProgramData\SAS\JMP\\

•

C:\ProgramData\SAS\JMP\

•

C:\Users\\AppData\Roaming\SAS\JMP\\

•

C:\Users\\AppData\Roaming\SAS\JMP\

•

C:\Users\\Documents\

On Macintosh, the following directories are examined in the order listed:
•

/Library/Application Support/JMP//

•

/Library/Application Support/JMP/

•

~/Library/Application Support/JMP//

•

~/Library/Application Support/JMP/

•

~/Documents/

Chapter 4
Scripting Guide

Scripting Tools
Using the Script Editor

63

Note that jmpKeywords.jsl is stored in the designated JMP directory, even if you are using JMP
Pro.
Notes:

•

The list in jmpKeywords.jsl is case insensitive.

•

Code folding is not supported for messages, platforms, user‐defined functions, and
comments.

•

After you edit and save the list in jmpKeywords.jsl, turn the Allow additional code folding
keywords preference off and then back on for the changes to take effect. Messages in the
log indicate that the keywords were loaded.

Advanced Options
Right‐clicking on selected text in the Script Editor provides the following Advanced options:
Option

Description

Expand All

(Appears only if JSL code folding is on) Expands all blocks of
code.

Collapse All

(Appears only if JSL code folding is on) Collapses all blocks of
code.

Comment Block

Makes the selected text comments.

Uncomment Block

Uncomments the selected comments.

Make Uppercase

Changes all selected text to uppercase.

Make Lowercase

Changes all selected text to lowercase.

Set Preferences for the Script Editor
In the JMP preferences, customize the script editor settings such as the font, colors, and
spacing options.
Setting the Fonts
1. Select File > Preferences.
2. Select the Fonts group.
3. Click Mono to set the font for the script editor.
For more details about font preferences, see the Using JMP book.

64

Scripting Tools
Using the Script Editor

Chapter 4
Scripting Guide

Figure 4.8 Changing the Font Properties for Script Windows

Set Script Editor Preferences
Select File > Preferences > Script Editor to further customize the editor.
Preference

Description

Use tabs

Select this option to enable tabs in your scripts. This option is
selected by default.
Clear this option to replace any tab that you type with spaces.

Tab width

Enter how many spaces a tab should indent. If you have disabled
tabs, any tab you type is replaced with the number of spaces
specified. The default value is 4.

Extra space at bottom
of document

Select this option to enable scrolling up from the last blank lines of
a script. This option is selected by default on Windows and
deselected on Macintosh.

Chapter 4
Scripting Guide

Scripting Tools
Using the Script Editor

65

Preference

Description

Auto-complete
parentheses and
braces

Select this option to enable the script editor to automatically add
closing parentheses, square brackets, and curly braces when you
type an opening one. This option is selected by default.

Show line numbers

Select this option to show the line numbers on the left side of the
script editor. This option is cleared by default.

Show indentation
guides

Select this option to see faint vertical lines that mark indention.
This option is selected by default.

Show operator tips

Select this option to see tooltips for JSL operators. This option is
selected by default.

Show variable value
tips

Select this option to see tooltips for variable values. This option is
selected by default.

Wrap Text

Select this option to always wrap text in the script editor. This
option is off by default.

Show embedded log on
script window open

Select this option to have an embedded log window appear in the
scripting window when editing or running scripts. This option is
deselected by default.

Color unknown object
messages

Select this option to cause the script editor to color object
messages that are not defined for the target object. Unknown
object messages will appear in the color specified by Message
unknown color.
Note: This option can affect the performance of the JSL editor due
to the amount of effort to look up message names in context.

Save and restore
document state
information

Saves the state of collapsed and expanded code, and restores that
state when the script is reopened.

Spaces inside
parentheses

Select this option to cause the script editor to add spaces between
parentheses, brackets, and braces and their contents for
automatically formatted scripts. This is on by default.

Spaces in operator
names

Select this option to cause the script editor to add spaces between
words within operator names. For example, turning on this
option results in New Window instead of NewWindow. This option is
selected by default.

66

Scripting Tools
Working with the Log

Chapter 4
Scripting Guide

Preference

Description

JSL code folding

Select this option to use code folding markers in the script editor,
which mark the opening and closing of Function() and Expr()
expressions. You can expand and collapse these marked blocks of
code. This option is off by default.
You can also choose the appearance of the marker using the JSL
code folding marker menu.

Select Allow additional code folding keywords to enable using
additional keywords for folding markers in the script editor. See
“Add More Folding Keywords” on page 62 for details.
Color selection

To set your own color for any of the listed types, click the color
box and select your color. See “Color Coding” on page 56 for
details on default settings.

For more details about script editor preferences, see the Using JMP book.

Working with the Log
As you run a script, the output appears in the log window. The actual script is shaded in the
log, and the output appears beneath it (Figure 4.9).
Figure 4.9 The Script Window (left) and the Log Window (right)

Syntax and compatibility errors are reported in the log, including the line number and code
that JMP could not process (Figure 4.10).

Chapter 4
Scripting Guide

Scripting Tools
Working with the Log

67

Figure 4.10 Syntax Error Message

Open the log by selecting View > Log (Window > Log on Macintosh).
Tips:
•

On Windows, you can control when the log opens: when JMP starts, when text is written
to the log, or only when you open it. Select File > Preferences > Windows Specific to
change the Open the JMP Log window setting.

•

To omit compatibility warnings from the log, deselect Show log warnings for JSL
compatibility changes in 12 in the JMP General preferences.

Show the Log in the Script Window
You can view the log inside the script window by right‐clicking and selecting Show
Embedded Log. This option makes it easy to edit and run a script, quickly see the results of
your changes, and then continue to develop the script.
The embedded log always appears in the Scripting Index script window but is not available in
Application Builder and the Debugger.

Save the Log
You can also save logs as text files, which can be viewed with any text editor. Double‐clicking
a log text file opens it in your default text editor, not in JMP.
1. Make the log window active (click the Log window to make it the front‐most window).
2. From the File menu, select Save or Save As.
3. Specify a filename, including the extension .txt on Windows. On Macintosh you cannot
save a log as a .txt file. .jsl is appended to the file name.
4. Click Save.

68

Scripting Tools
Debug or Profile Scripts

Chapter 4
Scripting Guide

Debug or Profile Scripts
In an open script, click the Debug Script button
(or select Edit > Debug Script) to show the
script in the JSL Debugger window. You can also use a keyboard shortcut:
•

Press CTRL + SHIFT + R (Windows).

•

Press SHIFT + COMMAND + R (Macintosh).

The JSL Debugger helps identify the point at which a script causes an error or fails. Rather
than commenting out portions of the script or adding Print() expressions, you can use the
Debugger to find the problem.
Once the JSL Debugger appears, you can continue in this mode, or you can click the Profile
JSL Script button
to move into the JSL Profiler mode. The JSL Profiler helps with
optimization. You can profile your scripts during execution to see how much time is spent
executing particular lines or how many times a particular line is executed.
Tip: To debug a script automatically when you open it, include Run JSL(1) in the Open()
statement:
Open( "$SAMPLE_SCRIPTS/scoping.jsl", Run JSL( 1 ) );

Debugger and Profiler Window
The Debugger opens in a new instance of JMP (Figure 4.11). The original instance is
inoperable until the script produces something that requires interaction. At that point, the
Debugger window becomes inoperable until you perform whatever action is required. Then
control is returned to the Debugger. Close the Debugger to work again in the original instance
of JMP.

Chapter 4
Scripting Guide

Scripting Tools
Debug or Profile Scripts

69

Figure 4.11 The Debugger Window

Use the buttons at the top to control the Debugger or the JSL Profiler. One or more scripts that
you are debugging or profiling are shown in tabs. If your script includes other scripts, each
one opens in a new tab.
Tabs in the bottom portion of the Debugger provide options to view variables, namespaces,
the log, and the current execution point; work with breakpoints; and set options.
Using the Execution Buttons
Use the buttons at the top to control execution of the script within the Debugger or JSL
Profiler.
Table 4.1 Description of the Debugger Buttons
Button

Button Name

Action

Run

Runs the script in the Debugger until it reaches either a
breakpoint or the end of the script.

Run without
breakpoints

Runs the script through the end without stopping.

Run profiler

70

Scripting Tools
Debug or Profile Scripts

Chapter 4
Scripting Guide

Table 4.1 Description of the Debugger Buttons (Continued)
Button

Button Name

Action

Break All

If the script is busy, click Break All to stop all action in the
script and return to the Debugger or JSL Profiler, for example,
if you are in a very long loop.
The Debugger or JSL Profiler may not be able to break
execution if the executing script is waiting on some interactive
user action, such as completing a dialog or interacting with an
opened window.

Stop

Stops debugging the script and exits the Debugger or the JSL
Profiler.

Restart

Closes the current Debugger session and opens a new session.

Step Into

Lets you step into a function or an included file. Otherwise, it
behaves the same as Step Over.

Step Over

Runs all expressions on a single line, or a complex expression
that spans multiple lines, without stepping into a called
expression, function, or Include() file.

Step Out

Runs the current script or function to a breakpoint or the end
and returns to the calling point. If you are in the main script
and the Debugger reaches the end, a message appears:
Program execution terminated. The Debugger remains open in
order for you to inspect the final program conditions.

Profile JSL
Script

Opens the JSL Profiler. (Press the Run profiler button to start
the JSL Profiler.) Use the JSL Profiler to see how much time is
spent executing particular lines or how many times a
particular line is executed. Note the following:

Show Profile
by Line Count

•

You can switch back and forth between the Debugger and
JSL Profiler modes only prior to the start of the program.

•

Some of the debugger buttons are disabled when profiling.

•

All breakpoints are disabled when running in the JSL
Profiler mode.

Shows the number of times each line is executed.

Chapter 4
Scripting Guide

Scripting Tools
Debug or Profile Scripts

71

Table 4.1 Description of the Debugger Buttons (Continued)
Button

Button Name

Action

Show Profile
by Time

Shows how much time is spent executing a line.

Show Profile
by Count

For line counts, shows the number of times the line is executed.
For time, shows the number of microseconds (or milliseconds
or seconds) the line takes to complete.

Show Profile
by Percent

For line counts, shows the individual line count divided by the
total line count. For time, shows the percentage of time spent
on an individual line (line time/total time*100).

Time Units

Sets the time unit to microseconds, milliseconds, or seconds.
Available in the JSL Profiler after you click the Run profiler
button
.

Color Theme

Sets the color of the shading for the JSL Profiler. Available in
the JSL Profiler after you click the Run profiler button
.

Variable Lists
The tabs on the bottom left of the Debugger let you examine global variables, local variables,
watch variables, and variables within namespaces.
Globals The Globals tab lists all global variables and updates their values as you step

through the script. Each variable is added as it is initialized. If there are already global
variables defined from running earlier scripts, they will be listed with their current values
when you start the Debugger. See “View Variables” on page 75.
Locals The Locals tab lists all variables by scope and updates their values as you step

through the script. Select a scope in the menu. See “View Variables” on page 75.
If there is a particular variable or value of an expression whose values you want to
watch as you step through the code, you can add them here. This is particularly useful if
your script uses many variables that might be hard to watch in the Globals or Locals lists.
See “Work with Watches” on page 75.

Watch

As namespaces are defined, they are added to the menu. Select a namespace to
view any variables and their values used within the namespace. See “View Variables” on
page 75.

Namespaces

Debugger Options
The tabs on the bottom right of the Debugger let you view the call stack, work with
breakpoints, set options, and view the log.

72

Scripting Tools
Debug or Profile Scripts

Chapter 4
Scripting Guide

Call Stack The call stack lists the current execution point in scripts and functions. The main

script is always the first script listed. If you call a function, the function is added on top of
the calling script. Likewise, any included files are added to the top of the list as you step
through them. When you exit any function or script, it is removed from the list and you
return to the next one in the list. The current line numbers are updated as you step
through.
Double‐click a row in the call stack to move the cursor to the specified line.
Breakpoints Add, edit, delete, and disable or enable breakpoints. See “Work with

Breakpoints” on page 72. You can also double‐click a row on the Breakpoints tab to move
the cursor to the specified line.
Options Set the Debugger preferences interactively on this tab. See “Modify Preferences in

Debugger” on page 76.
Log

The log from the script that you are debugging is shown on this tab.

Work with Breakpoints
A breakpoint interrupts the execution of a script. Although you can step through a script line by
line, this can be tedious and lengthy for a long or complex script. You can set breakpoints at
places of interest and simply run the script in the Debugger. The script is run normally until a
breakpoint is reached. At the breakpoint, the Debugger stops executing the script so you can
look at the values of variables or start stepping line by line.
JMP preserves breakpoints across sessions. So when you close and reopen JMP, the
breakpoints still appear.
Tip: Turn on line numbers by right‐clicking in the script and selecting Show Line Numbers.
You can also show line numbers by default in all scripts by modifying the Script Editor
preferences.
Create a Breakpoint
When creating a breakpoint, you can specify settings such as conditions and break behavior.
To do so, click
on the Breakpoints tab, and then enter the breakpoint information.
Otherwise, create a quick breakpoint by doing one of the following:
•

In the Debugger margin, click on the appropriate line (to the right of the line number if
displayed).

•

In the Debugger margin, right‐click in the margin where you want the breakpoint and
select Set Breakpoint.

The red breakpoint icon appears where you inserted the breakpoint and on the Breakpoints
tab.

Chapter 4
Scripting Guide

Scripting Tools
Debug or Profile Scripts

73

Delete Breakpoints
Do one of the following:
•

In the Debugger margin, click the breakpoint icon.

•

In the Debugger margin, right‐click the breakpoint icon and select Clear Breakpoint.

•

On the Breakpoints tab, select the breakpoint and then click

•

On the Breakpoints tab, click
breakpoints).

.

to delete all breakpoints (not just the selected

The red breakpoint icon is removed, and the breakpoint no longer appears on the Breakpoints
tab.
Disable and Enable Breakpoints
Disabling a breakpoint is helpful when you potentially fix a problem and then want to see
whether the script will run correctly past that breakpoint. You can then enable the breakpoint
when necessary rather than recreating it.
Do one of the following:
•

In the Debugger margin, right‐click the breakpoint icon and select Enable Breakpoint or
Disable Breakpoint.

•

On the Breakpoints tab, select or deselect the breakpoint’s check box.

•

On the Breakpoints tab, click

to disable or enable all breakpoints.

A disabled breakpoint turns white; enabled breakpoints are shaded red.
Specify and Clear Conditional Expressions on Breakpoints
Setting a condition on a breakpoint is an alternative to single‐stepping through code. Rather
than single‐step and view the variables for each expression, you specify that the script break
only when a condition is met. Then you can step through the code and figure out where the
problem arises.
Suppose that a calculation in your script is incorrect, and you suspect the problem occurs
when i==19. Set a conditional breakpoint for i==18. The Debugger will run until that
condition is met, then you can step through the code to identify the problem.
Specify a Breakpoint Condition
1. Right‐click the breakpoint icon and select Edit Breakpoint.
2. On the Condition tab, select Condition and enter the conditional expression.
3. Specify whether to break when the expression Is true or Has Changed.
4. Click OK.

74

Scripting Tools
Debug or Profile Scripts

Chapter 4
Scripting Guide

Disable or Enable a Condition
1. Right‐click the breakpoint icon and select Edit Breakpoint.
2. On the Condition tab, deselect or select Condition.
Delete a Condition
On the Breakpoints tab, click in the breakpoint’s Condition field and press DELETE.
Specify Break Options
Right‐clicking the breakpoint and selecting Edit Breakpoint provides a quick way to manage
breakpoint behavior. Alternatively, select the breakpoint on the Breakpoints tab and click
.
Both methods display the Breakpoint Information window, where you customize settings on
the Hit Count and Action tabs.
Change the Hit Count
You can control the number of times a breakpoint must be hit and when the break occurs. For
example, to break when the condition is met twice, select break when the hit count is equal to
and type 2 on the Hit Count tab.
Define an Action
You also have the option of defining a JSL expression or script that the Debugger executes
when a breakpoint is hit and execution has stopped. This script is called an action. On the
Action tab, enter the JSL expression to be executed.
Run the Script to the Cursor
When you right‐click and select Run To Cursor, all expressions before the location of the cursor
are executed. Select this option when you only want to see values up to the current line. To see
values when each expression is executed, use the stepping options.
Tips for Setting Breakpoints
•

If you do not want to watch for errors in a specific loop, set a breakpoint after the loop
ends. The Debugger will hit the next breakpoint rather than stepping through each line of
the loop.

•

Avoid inserting a breakpoint in lines that do not trigger an action (such as comments,
blank lines, and end parentheses). Debugger will not break on these lines.

•

When you insert breakpoints, close Debugger, and edit the script, the breakpoints remain
on the original line numbers. You might need to delete and then reinsert the breakpoints.

Chapter 4
Scripting Guide

Scripting Tools
Debug or Profile Scripts

75

•

Breakpoints are remembered across Debugger sessions. This means that your breakpoints
list includes breakpoints that have been set in all scripts, not just the script that you are
currently debugging.

•

Breakpoints are remembered by the Debugger session, not by each script. This means that
breakpoints are listed even for scripts that have been moved or deleted.

•

On the Breakpoints tab, click
to remove all breakpoints in scripts whether they are
currently open or not, or for scripts that no longer exist.

View Variables
The variables lists are populated as they appear in the script. Their values are updated every
time the script changes them. If you are uncertain why a variable has a particular value when
you run your script, you can watch its value at every step to see what happens.
You can also assign the variables whatever value you want. For example, if you are stepping
through a For() loop but are interested only in what happens starting with a particular
iteration, you can assign your iterating variable that value. Step through the first part of the
loop that initializes the iteration variable and then assign it the value that you want in the
variable list at the bottom. Then when you step through, the loop begins executing at that
point.
Tips for Managing Variables
•

If you have run several scripts using the global scope, you might want to clear or delete
global variables. This makes the list of variables in the Debugger shorter and relevant. Use
the Delete Symbols() function to do so. You can also close JMP and restart to clear the
space.

•

If your script uses so many variables that they are difficult to find and watch in the
variable lists, add watches for the specific variables in which you are interested.

Work with Watches
JMP preserves the Watch variables across sessions. So when you close and reopen JMP, the
Watch variables are still listed on the Watch tab.
Create a Watch
•

On the Watch tab, click

and enter the value in the window.

•

In the Debugger, right‐click the line that you want to watch, select Add Watch, and then
enter the variable name in the window.

•

In the Debugger, place the cursor in or next to a variable name (or select the variable
name), right‐click, and select Add Watch.

76

Scripting Tools
Debug or Profile Scripts

•

Chapter 4
Scripting Guide

On the Watch tab, enter the variable in an empty Variable field.

Modify a Watch
Do one of the following on the Watch tab to enter a new value:
•

Select the watch and click

.

•

Click in the Variable field and enter a new value.

Delete Watches
Do one of the following on the Watch tab to delete watches:
•

Select the watch and then click

•

Click

.

to remove all watches.

Modify Preferences in Debugger
The Debugger lets you change preferences as you work in the Debugger. Select the Options
tab to find the following settings:
Show Line Numbers Shows or hides the line numbers for the script in the Debugger.
Break on Multiple Statements Per Line

Stops executing the script between each expression in

a single line.
Breaks when the script executes the Throw() function. For example, Throw()
might be enclosed in a Try() expression. The Debugger breaks on Throw() instead of
continuing through the rest of the expression. This lets you identify where the problem
occurred in the script and then return to debugging.

Break On Throw

Break On Execution Error Stops executing the script when the error occurs rather than closing

the Debugger.
Warn On Assignment In Condition Shows a warning when you enter a breakpoint condition
that contains the assignment. For example, if you have a breakpoint on x = 1 and add the
condition x = 1 to the breakpoint, you are prompted to verify the assignment of x.
Enter Debugger Upon Termination Keeps the Debugger open after a JSL program terminates

execution. On by default, this option lets you examine attributes of the executed program.

Persistent Debugger Sessions
JMP saves all breakpoints and watches until you delete them. Other user‐specific settings,
such as column widths on the tabs and the Debugger window size, persist between sessions of
JMP.

Chapter 4
Scripting Guide

Scripting Tools
Debug or Profile Scripts

77

These settings are stored in a file named JMP.jdeb, the location of which is defined in the
USER_APPDATA variable:
•

Windows 7: "/C:/Users//AppData/Roaming/SAS/JMP//"

•

Macintosh: "/Users//Library/Application Support/JMP//"

As usual, the values of local variables, global variables, and namespaces clear when you close
and reopen JMP.
Note: On Windows, the paths differ based on the JMP edition. In JMP Pro, the path refers to
“JMPPro”. In JMP Shrinkwrap, the path refers to “JMPSW”.

Examples of Debugging and Profiling Scripts
This section includes examples of setting breakpoints to watch variables; stepping into, over,
and out of expressions; watching variables in different scopes and namespaces; debugging
interactive scripts; and profiling scripts with the JSL Profiler.
Example scripts are located in the Samples/Scripts folder.
Tip: Make sure that Show Line Numbers is selected on the Debugger Options tab before
proceeding.
Using Breakpoints and Watching Global Variables
The following example shows how to set a breakpoint in a loop and watch variables change
through each iteration of the loop.
1. Open the string.jsl sample script and click the Debug Script button.
2. Click in the margin for line 12 to add a breakpoint (Figure 4.12).
You should have a breakpoint for the following expression inside the For() loop:
stringFunction(i);

78

Scripting Tools
Debug or Profile Scripts

Chapter 4
Scripting Guide

Figure 4.12 Set the Breakpoint

3. Click Run.
The first two expressions are evaluated:
‒ stringFunction is defined as a function.
‒ str is defined as an empty string.
Both variables and their types and values have been added to the Globals list. In addition,
the For() loop has been evaluated up to the line with the breakpoint, shown in
Figure 4.12.
‒ i has been assigned to 0.
‒ i and its value and type have been added to the Globals list.
‒ i has been determined to be less than or equal to 9.
‒ stringFunction() has not yet been called.
Figure 4.13 View the Initial Global Variables

4. Click Run again.
The script runs until it hits the breakpoint. The results are shown in Figure 4.14.
‒ stringFunction() is called, evaluated, and returns to the loop.
‒ i is incremented and determined to be less than or equal to 9.
‒ In the Globals list, i is now 1 and str is now “0”.

Chapter 4
Scripting Guide

Scripting Tools
Debug or Profile Scripts

79

Figure 4.14 Global Variables at First Breakpoint

5. Click Run again.
The script runs until it hits a breakpoint. The results are shown in Figure 4.15.
‒ stringFunction() is called, evaluated, and returns to the loop.
‒ i is incremented and determined to be less than or equal to 9.
In the Globals list, i is now 2, and str is now “01”.
Figure 4.15 Global Variables at Second Breakpoint

You can continue to click Run and watch i and str change with each iteration of the loop. Or,
click Run without breakpoints to complete running the script and exit the Debugger.
Stepping Into, Over, and Out
Step Into, Step Over, and Step Out offer flexibility when your script contains expressions,

functions, or includes other JSL files.
1. Open the scriptDriver.jsl sample script and click the Debug Script button.
2. This script writes information to the log, so select the Log tab at the bottom of the
Debugger to view the messages.
3. Click Step Over.
The first line in the script is evaluated.
4. Click Step Over again.
The current expression is evaluated, and the Debugger moves to the following line. In this
case, the expression is a few lines long, and it assigns an expression to a variable.
5. Click Step Over again.
This expression is several lines long, and assigns a function to a variable.
Line 30 calls the expression that was created earlier.
6. Click Step Over.

80

Scripting Tools
Debug or Profile Scripts

Chapter 4
Scripting Guide

The Debugger steps into the expression, running it line by line.
7. Continue clicking Step Over until the expression ends.
The Debugger returns to the line following the expression call.
Line 31 calls the function defined earlier.
8. Click Step Over to run the function without stepping into it. The Debugger runs the entire
function, and returns to the line following the function call.
Line 33 includes another script.
9. Click Step Into.
The Debugger opens the script in another tab and waits.
10. Click Step Over.
The next line in the included script is run.
11. Click Step Out.
The Debugger runs the rest of the included script and returns to the line following the
Include() function.

Watching Variables in Different Scopes and Namespaces
Tabs at the bottom of the Debugger window let you watch variables as they are created and
changed. This example shows variables in several scopes and a namespace.
1. Open the scoping.jsl sample script and click the Debug Script button.
2. Click Step Over.
The fourth line turns off Names Default To Here. If you run this script again in the same
JMP session, this line resets the scoping so that the first variable that is created is in the
global scope.
3. Click Step Over.
A global variable named x is created. On the Globals tab, x has been added to the list,
showing its value as 5 and its type as number.
4. Select the Locals tab, and then select Global from the list of scopes.
The global variable x is also shown here.
5. Click Step Over twice.
Names Default To Here is turned on, which places the rest of the script into a Here scope.
Then a new variable x is created in that scope.

Notice that the value of the global variable x has not changed.
6. Select Here from the list on the Locals tab.
The local x is listed under Here, with its value and type.

Chapter 4
Scripting Guide

Scripting Tools
Debug or Profile Scripts

81

7. Click Step Over.
A Local Here scope is created. A second Here scope is shown in the Locals list.
8. Click Step Over.
A new x variable is created in this Here scope. On the Locals tab, select each of the three
scopes from the list (Here, Here, and Global) to see three different x variables.
9. Click Step Over.
Look in the Debugger’s log to see the output. Notice that here:x scopes to the local here,
not the script window’s here.
10. Click Step Over.
After writing an empty line to the log, the script exits the Local Here scope. The second
Here, along with its’ x variable, has disappeared from the Locals list.
11. Click Step Over.
A namespace called “test” is created, with another variable named x. Select the
Namespaces tab to see it.

12. Click Step Over and look at the log.
13. Click Step Over to exit the Debugger.
Using the Debugger with Interactive Scripts
When your script creates interactive elements, the Debugger hands control back to the main
instance of JMP so that you can interact with it. When you are finished, control returns to the
Debugger.
1. Open the interactive.jsl sample script and click the Debug Script button.
2. Click Step Over twice.
The New Window expression is evaluated, and a modal window waiting for input is created.
You might need to move the Debugger window to see the new modal window.
3. Enter two numbers in the Assign X and Y window and click OK.
Control is given back to the Debugger.
4. Click Step Over three times and look at the log in the Debugger.
The log shows the two new numbers that you entered in the window.
5. Click Step Into to exit the Debugger.
Using the JSL Profiler
Use the JSL Profiler to see how much time is spent executing particular lines or how many
times a particular line is executed.
1. Open the string.jsl sample script.

82

Scripting Tools
Debug or Profile Scripts

Chapter 4
Scripting Guide

2. Click the Debug Script button

.

3. Click the Profile JSL Script button

.

Figure 4.16 Initial JSL Profiler Window

4. Click the Run button

to start profiling.

The profiler collects information on the number of times a statement is executed and the
time it takes to execute it. Time is cumulative and collected each time a JSL statement is
executed.
Figure 4.17 Profiled Script Window

In the left margin, the selected statistics are displayed. Percent of time is displayed by default.
Click the Show Profile by Count button
to switch to percent of statement counts instead.
The left margin is color‐coded to allow for quick identification of problematic performance
areas.

Chapter 5
JSL Building Blocks
Learning the Basics of JSL
Studying the syntax and basics of JSL is crucial, whether you are a beginning or an advanced
user. Some concepts (such as loops and variables) are common among many scripting
languages, but punctuation rules differ in JSL.
Figure 5.1 Example of a JSL Script
comment

multiplication
operator

concatenate
operator

quoted text string

variables

functions

Commas separate
arguments.

Semicolons separate
certain expressions.

This chapter introduces you to the basic concepts of JSL, from syntax rules and file path
conventions to conditions and namespaces.

Contents
JSL Syntax Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Value Separators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Global and Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Local Namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Named Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Show Symbols, Clear Symbols, and Delete Symbols. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Lock and Unlock Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Rules for Name Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Resolving Unscoped Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Troubleshooting Variables and Column Names. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Troubleshooting Variables and Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Alternatives for Gluing Expressions Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Iterate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Summation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Break and Continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Conditional Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
If . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Match . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Choose. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Interpolate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Step . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Compare Incomplete or Mismatched Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Inquiry Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

Chapter 5
Scripting Guide

JSL Building Blocks
JSL Syntax Rules

85

JSL Syntax Rules
All scripting and programming languages have their own syntax rules. JSL looks familiar if
you have programmed in languages such as C and Java. However, rules for punctuation and
spaces differ in JSL.
The following sections describe JSL syntax rules for the following basic components of the
language:
•

“Value Separators” on page 85

•

“Numbers” on page 88

•

“Names” on page 88

•

“Comments” on page 89

Value Separators
Words in JSL are separated by parentheses, commas, semicolons, spaces, and various
operators (such as +, –, and so on). This section describes the rules for using these separators
and delimiters in JSL.
Commas
A comma separates items, such as items in a list, rows in a matrix, or arguments to a function.
my list = {1, 2, 3};
your list = List(4, 5, 6);
my matrix = [3 2 1, 0 -1 -2];
If(Y < 20, X = Y);
If(Y < 20, X = Y; Z < 3, A);
TableBox(
stringColBox("Age",a),
NumberColBox("Count",c),...)

Note: To glue a sequence of commands into a single argument inside a function, separate each
sequence with a semicolon. For more information, see “Semicolons” on page 86.
Parentheses
Parentheses have several purposes in JSL:
•

Parentheses group operations in an expression. The following parentheses group the
operations in the If() expression.
If(
Y < 20, X = Y,

86

JSL Building Blocks
JSL Syntax Rules

Chapter 5
Scripting Guide

X = 20
);

•

Parentheses delimit arguments to a function. In the following example, parentheses
enclose the argument to the Open() function.
Open("$SAMPLE_DATA/Big Class.jmp")

•

Parentheses also mark the end of a function name, even when arguments are not needed.
For example, the Pi function has no arguments. However, the parentheses are required so
that JMP can identify Pi as a function.
Pi();

Note: Be careful that parentheses match. Every ( needs a ), or errors result.
The script editor can match fences (parentheses, brackets, and braces). Press CTRL‐]
(COMMAND‐b on Macintosh) 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 that it finds.
Repeat this process to highlight the next‐higher fence. See “Match Parentheses, Brackets, and
Braces” on page 59 in the “Scripting Tools” chapter for an example.
Semicolons
Expressions separated by a semicolon are evaluated in succession, returning the result of the
last expression. In the following code, 0 is assigned to the variable i and then 2 is assigned the
variable j.
i=0;
j=2;

You can also use semicolons to join arguments that are separated by commas as shown in the
following If() expression.
If(x <5, y = 3; z++; ...);

The semicolon in other languages is used as an expression terminator character. In JSL, the
semicolon is a signal to continue because more commands might follow. For details about
separating expressions with semicolons, see “Alternatives for Gluing Expressions Together”
on page 104.
Semicolons at the end of a script or at the end of a line of arguments are harmless, so you can
also think of semicolons as terminating characters. Trailing semicolons are allowed at the end
of a script stream and after a closing parenthesis or closing curly brace. In fact, terminating
each complete JSL expression with a semicolon helps avoid errors when you copy and paste
small scripts into a larger one.
The semicolon is equivalent to the Glue() function. See “Operators” on page 90 for more
information about semicolons and Glue().

Chapter 5
Scripting Guide

JSL Building Blocks
JSL Syntax Rules

87

Double Quotes
Double quotes enclose text strings. Anything inside double quotes is taken literally, including
spaces and upper‐ or lower‐case; nothing is evaluated. If you have "Pi() ^ 2" (inside double
quotes), it is just a sequence of characters, not a value close to ten.
You do have to be a careful with text strings. Extra spaces and punctuation do affect the
output, because text strings inside double quotes are used literally, exactly as you enter them.
To have double quotes inside a quoted string, precede each quotation mark with the escape
sequence \! (backslash‐bang). For example, run the following script and look at the title of the
window:
New Window( "\!"Hello\!" is a quoted string.",
Text Box( Char( Repeat( "*", 70 ) ) )
);

Table 5.1 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
Note: The null character is dangerous to use, because it is
typically treated as the end of the string. Be sure to type the
number zero, not the letter O.

\!\

backslash

\!"

double quotation mark

a. On Macintosh, this escape sequence is CR (carriage return character,
hexadecimal ‘0D’). On Windows, this sequence is CR LF (carriage
return followed by a linefeed, hexadecimal ‘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.
Here is an example where \[...]\ is used inside a double‐quoted string.
jslPhrase = "The JSL to do this is :\[

88

JSL Building Blocks
JSL Syntax Rules

Chapter 5
Scripting Guide

a = "hello";
b = a|| " world.";
show(b);
]\ and you use the Submit command to run it.";

Spaces
JSL allows whitespace characters inside names; spaces, tabs, returns, and blank lines inside or
between JSL words are ignored. This is because most JSL words come from the user interface,
and most of those commands have spaces in them. For example, the JSL expression for the Fit
Model platform is Fit Model() or FitModel().
Spaces inside an operator or between digits in a single number are not allowed. In these cases,
the script generates errors. For example, you cannot put spaces between the two plus signs in
i++ (i+ +) or in numbers (4 3 is not the same as 43).
Note: Why does JSL allow whitespace characters inside names? For one reason, the names of
commands and options match the equivalent commands in JMP menus and windows.
Another reason is that data table column names often include spaces.

Numbers
Numbers can be written as integers, decimal numbers, dates, times, or datetime values. They
can also be included in scientific notations with an E preceding the power of ten. For example,
these are all numbers:
.

1

12

1.234

3E3

0.314159265E+1 1E-20 01JAN98

Note: A single period by itself is considered a missing numeric value (sometimes called NaN
for “not a number”).
For more information about dates, times, and date‐time values, see “Date‐Time Functions and
Formats” on page 130 in the “Types of Data” chapter. See “Currency” on page 142 in the
“Types of Data” chapter for details about combining numbers with currency symbols.

Names
A name is simply something to call an item. When you assign the numeric value 3 to a variable
in the expression a = 3, a is a name.
Commands and functions have names, too. In the expression Log( 4 ), Log is the name of the
logarithmic function.
Names have a few rules:

Chapter 5
Scripting Guide

•

JSL Building Blocks
JSL Syntax Rules

89

Names must start with an alphabetic character or underscore and can continue with the
following:
‒ alphabetic characters (a‐z A‐Z)
‒ numeric digits (0‐9)
‒ whitespace characters (spaces, tabs, line endings, and page endings)
‒ mathematical symbols in Unicode (such as )
‒ a few punctuation marks or special characters (apostrophes (‘), percent signs (%),
periods (.), backslashes (\), and underscores (_))

•

When comparing names, JMP ignores whitespace characters (such as spaces, tabs, and line
endings). Upper case and lower case characters are not distinguished. For example, the
names Forage and for age are equivalent, despite the differences in white space and case.

You can still have a name that is any other sequence of characters. If the name does not follow
the rules above, it needs to be quoted and placed inside a special parser directive called
Name(). For example, to use a global variable with the name taxable income(2011), you must
use Name() every time the variable appears in a script:
Name("taxable income(2011)") = 456000;
tax = .25;
Print(tax * Name("taxable income(2011)"));
114000
Name() is harmless when it is not needed. For example, tax and Name("tax") are equivalent.

For more information about how JMP interprets names, see “Rules for Name Resolution” on
page 97.

Comments
Comments are notes in the code that are ignored by the JSL processor (or parser). You include
comments to describe sections of the script. Comments are also convenient for removing
portions of a script temporarily. For example, you can insert comment symbols around code
that might be causing an error and then rerun the script.
Type the comment symbols around code that you want to comment. The following example
shows code commented with /* */ in the middle of a line. When the script is run, JMP
considers both expressions to be identical.
tax /*percentage*/ = .25;
tax = .25;

Table 5.2 describes the comment symbols.

90

JSL Building Blocks
Operators

Chapter 5
Scripting Guide

Table 5.2 Comment Symbols
Symbol

Syntax

Explanation

//

// comment

Begins a comment. The comment does not have to be at the
beginning of a line, but everything up to the end of the line is
a comment.

/* */

/* comment */

Begins and ends a comment. This comment can appear in the
middle of a line. Script text before and after the comment is
parsed normally.

//!

//!

Add //! to the first line of the script, and the script runs
automatically when opened in JMP. (In other words, the
script editor does not open.)

Operators
Operators are one‐ and two‐character symbols for common arithmetic actions. Operators
come in several varieties:
•

infix (with arguments on either side, such as + in 3 + 4, or = in a = 7)

•

prefix (with one argument on its right side, such as !a for logical negation)

•

or postfix (with one argument on its left side, such as a++ for incrementing a)

JSL operators all have function equivalents.
To make writing algebraic expressions easier, JSL uses certain special character operators.
These operators have the same meaning as if the phrase had been written as a function. For
example, the following two expressions 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 the Assign() function or as an infix
operator =. Similarly, subtraction can be done with the Subtract() function or the infix minus
sign; they are equivalent inside JMP.
Note: Usually white space is ignored in JSL, so that “netincomeaftertaxes” and “net income
after taxes” are the same thing. There is one exception: the two‐character operators must not
have a space between characters. Always enter the following operators without spaces in
between:
||, |/, <=, >=, !=, ==, +=, -=, *=, /=,

++, --, <<, ::, :*, :/, /*, */

Another common operator is the semicolon ( ; ). You use the semicolon to:

Chapter 5
Scripting Guide

JSL Building Blocks
Operators

91

•

Separate yet join one expression to another in a programming sequence. The semicolon
returns the result of its last argument, so a;b is the same as Glue(a,b).

•

End an expression. Though the semicolon is permitted at the end of an expression, it is not
the expression terminator used in other languages.

An expression can contain more than one operator. In these instances, the operators are
grouped in order of precedence with decreasing priority. For example, * takes precedence
over +:
a + b * c

So b * c is evaluated first, and then the result is added to a.
+ takes precedence over -:
a + b * c - d

So b * c is evaluated, and then the result is added to a. d is then subtracted from the result of
a + b * c.
Table 5.3 shows operators shaded in order of precedence and each operator’s function
equivalent.
Table 5.3 Operators and Their Function Equivalents in Order of Precedence
Operator

Function Syntax

Explanation

{ }

List

{a,b}
List(a,b)

Construct a list.

[ ]

Subscript

a[b,c]

Subscripts identify specific
elements within a data element a,
where a could be a list, a matrix, a
data column, a platform object, a
display box, and so on.

Subscript(a,b,c)

++
––
^

Post
Increment

a++

Post
Decrement

a––

Power

a^b

Post Increment(a)
Post Decrement(a)
Power(a,b)
Power(x)

–

Minus

–a
Minus(a)

Adds one (1) to a, in place.
Subtracts one (1) from a, in place.
Raise a to exponent power b. With
only one argument, 2 is assumed as
the power, so Power(x) computes
x2.
Reverses sign of a.

92

JSL Building Blocks
Operators

Chapter 5
Scripting Guide

Table 5.3 Operators and Their Function Equivalents in Order of Precedence (Continued)
Operator

Function Syntax

Explanation

!

Not

!a
Not(a)

Logical Not. Maps nonzero (or
true) values to 0 (which means
false). Maps 0 (or false) values to 1
(which means true).

*

Multiply

a*b

Multiplies a by b.

Multiply(a,b)
:*

EMult

a:*b
EMult(a,b)

/

Divide

a/b
Divide(a,b)
Divide(x)

Elementwise multiplication for
matrices a and b. (Each element in
matrix a is multiplied by each
element in matrix b.)
Divide(a, b) divides a by b.
Divide(x) interprets the argument

as a denominator and implies 1 as
the numerator, yielding the
reciprocal 1/x.
:/

EDiv

a:/b
EDiv(a,b)

+

Add

a+b
Add(a,b)

–

Subtract

a–b
Subtract(a,b)

||

Concat

a||b
Concat(a,b)

|/

VConcat

matrix1|/matrix2
VConcat(matrix1,
matrix2)

Elementwise division for matrices a
and b. (Each element in matrix a is
divided by each element in matrix
b.)
Adds a and b.
Subtracts b from a.
Joins two or more strings; two or
more lists; and horizontally
concatenates matrices. See
“Concatenate Lists” on page 172 in
the “Data Structures” chapter or
the JSL Syntax Reference for details.
Vertically concatenate matrices.
(Use || or Concat() to horizontally
concatenate matrices.)

Chapter 5
Scripting Guide

JSL Building Blocks
Operators

Table 5.3 Operators and Their Function Equivalents in Order of Precedence (Continued)
Operator
::

Index

Function Syntax

Explanation

a::b

For matrices, generates the integers
from a to b.

Index(a,b)

(Colons are also used as prefix
operators for scoping, where :a
means data table column a, and ::a
means JSL global variable a. See
“Scoping Operators” on page 98 for
details.)
<<

Send

object << message
Send(object, message)

Send message to object.

==

Equal

a==b

Boolean values for comparisons.
They all return 1 if true, 0 if false.
Missing values in either a or b
causes a return value of missing,
which evaluates as neither true nor
false. See “Missing Values” on
page 117, for treatment of missing
values.

Equal(a,b)...
!=

Not Equal

a!=b
Not Equal(a,b)...

<

Less

a

Greater

a>b
Greater(a,b)

>=
<=, <
<, <=
&

Greater or
Equal

a>=b

Less Equal
Less

a<=b Stop Script. On Macintosh, Edit > Stop Script is available only when the script is
running.

Comparing For Loops in JSL to C and C++
The JSL For() loop works just like it does in the C (and C++) programming language,
although the punctuation is different.
Tip: If you know C, watch out for the difference between JSL and C in the use of semicolons
and commas. In JSL, For() is a function where commas separate arguments and semicolons
join expressions. In C, for is a special clause where semicolons separate arguments and
commas join them.

106

JSL Building Blocks
Iterate

Chapter 5
Scripting Guide

While
A related function is While(), which repeatedly tests the condition and evaluates its body
script as long as the condition is true. The syntax is:
While(condition, body);

For example, here are two different programs that use a While() loop to find the least power
of 2 that is greater than or equal to x (287). The result of both programs is 512.
x = 287;
// loop 1:
y = 1;
While(y < x, y *= 2);
Show(y);
// loop 2:
k = 0;
While(2 ^ k < x, k++);
Show(2 ^ k);

The scripts work like this:
x = 287;

Sets x to 287.

// loop 1
y = 1;

Sets y to 1.

While(

Begins the While() loop.

y < x,

As long as y is less than x, continues evaluating the
loop.

y *= 2

Multiplies 1 by 2 and then assigns the result to y. The
loop then repeats while y is less than 287.

);

Ends the loop.

Show(y);

Shows the value of y (512).

// loop 2
k = 0;

Sets k to 0.

While(

Begins the While() loop.

2 ^ k < x,

Raises 2 to the exponent power of k and continues
evaluating the loop as long as the result is less than 287.

Chapter 5
Scripting Guide

JSL Building Blocks
Iterate

k++

107

Increments k to 1. The loop then repeats while 2 ^ k is
less than 287.

);

Ends the loop.

Show(2 ^ k);

Shows the value of 2 ^ k (512).

As with For() loops, Which() loops that always evaluate as true create an infinite loop, which
never stops. To stop the script, press ESC on Windows (or COMMAND‐PERIOD on
Macintosh). You can also select Edit > Stop Script. On Macintosh, Edit > Stop Script is
available only when the script is running.

Summation
The Summation() function adds the body results over all i values. The syntax is:
Summation(initialization, limitvalue, body);

For example:
s = Summation(i = 1, 10, i);

returns 55, the result of 1+2+3+4+5+6+7+8+9+10.
The script works like this:
s =

Sets the s variable to the value of the function.

Summation(

Begins the Summation() loop.

i = 1,

Sets i to 1.

10,

Sets the limit of i to 10.

i

All values of i from 1 to 10 are added together,
resulting in 55.

);

Ends the loop.

This behavior is similar to  in the Formula Editor. The following expression:
Summation(i = 1, N Row(), x ^ 2);

is equivalent to the following formula in the Formula Editor:
NRow 2
x

i = 1

108

JSL Building Blocks
Iterate

Chapter 5
Scripting Guide

Product
The Product() function is similar to Summation() except that it multiplies the body results
rather than adding them. The syntax is the same as for Summation(). For example:
p = Product(i = 1, 5 , i);

returns 120, the result of 1*2*3*4*5.
In this example, the initial value of i is 1, the upper limit is 5, then all integer values of i up to
5 are multiplied.
Here is the equivalent in the Formula Editor:
5

i = 1 i
Break and Continue
The Break() and Continue() functions give you more control over looping. Break()
immediately stops the loop and proceeds to the next expression that follows the loop.
Continue() is a gentler form of Break(). It immediately stops the current iteration of the loop
and continues with the next iteration of the loop.
Break
Break() is typically used inside a conditional expression. For example:
For(i = 1, i <= 5, i++,
If(i == 3, Break());
Print("i=" || Char(i));
);

results in:
"i=1"
"i=2"

The script works like this:
For(

Begins the For() loop.

i = 1,

Sets i to 1.

i <= 5,

As long as i is less than or equal to 5, continues
evaluating the loop.

i++,

Increments i by 1. Note that this step is done after the
If loop is evaluated.

Chapter 5
Scripting Guide

JSL Building Blocks
Iterate

If(
i == 3, Break()

109

Begins the If() loop.
If i is equal to 3, breaks the loop.

);

Ends the loop.

Print(

When i equals 3, opens the Print() loop.

"i="

Prints the string "i=" to the log.

||

Places "i=" on the same line as the value that follows.

Char(i));

Prints the value of i to the log.
The For() loop then repeats until the value of i is less
than or equal to 5, breaking and printing only when i is
less than 3.

);

Ends the loop.

Note that when the If() and Break() expressions follow Print(), the script prints the values
of i from 1 to 3, because the loop breaks after ʺi=3ʺ is printed.
"i=1"
"i=2"
"i=3"

Continue
As with Break(), Continue() is typically used inside a conditional expression. For example:
For(i = 1, i <= 5, i++,
If(i < 3, Continue());
Print("i=" || Char(i));
);

results in:
"i=3"
"i=4"
"i=5"

The script works like this:
For(

Begins the For() loop.

i = 1,

Sets i to 1.

i <= 5,

Evaluates 1 as less than or equal to 5.

110

JSL Building Blocks
Conditional Functions

Chapter 5
Scripting Guide

i++,

Increments i by 1. Note that this step is done after the
If loop is evaluated.

If(

Begins the If() loop.

i < 3, Continue()

Evaluates i as 1 and continues as long as i is less than 3.

);

Ends the If() loop.

Print(

When i is no longer less than 3, opens the Print() loop.

"i="

Prints the string "i=" to the log.

||

Places "i=" on the same line as the value that follows.

Char(i));

Prints the value of i to the log.
The For() loop then repeats until the value of i is less
than or equal to 5, continuing and printing only when i
is equal to or greater than 3.

);

Ends the loop.

Conditional Functions
JSL provides five functions to evaluate an expression conditionally: If(), Match(), Choose(),
Interpolate(), and Step().

If
The If() function evaluates the first result expression when its condition evaluates as true (a
nonzero or nonmissing value). Otherwise, it evaluates the second result expression.
The syntax is:
If (condition, result1, result2)

For example, the following script returns ʺYoungʺ when the age is less than 12. Otherwise, the
script returns ʺYoung at Heartʺ.
If (age < 12,
"Young",
"Young at Heart"
);

You can also string together multiple conditions and results. The syntax is:
If (condition1, result1,
condition2, result2,

Chapter 5
Scripting Guide

JSL Building Blocks
Conditional Functions

111

...,
resultElse);

In the preceding example, if condition1 is not true, the function continues evaluating until it
finds a true condition. Then that condition’s result is returned.
The last result is returned when all conditions are false. And when a value is missing, the
missing value is returned. For these reasons, it’s very important to include a default result at
the end of the expression. Consider the following example, which recodes gender
abbreviations in Big Class.jmp:
For Each Row(sex =
If(
sex == "F", "Female",
sex == "M", "Male",
"Unknown");
);

The script works like this:
For Each Row(sex =

For each row in the table, sex is the column that is
recoded.

If(

Begins the If() loop.

);

sex == "F", "Female",

If the value of sex is F, replaces the value with Female.

sex == "M", "Male",

If the value of sex is M, replaces the value with Male.

"Unknown");

If neither of the above conditions are true, replaces the
value with Unknown. If this result were omitted and
the value of sex were missing, the script would return a
missing value.
Ends the loop.

You can also put actions and assignments in the result expression. The following example
assigns 20 to x, because the first condition (y < 20) is false:
y = 25;
z = If( y < 20, x = y, x = 20 );

Note: Be careful to use two equal signs (==) for equality tests, not one equal sign (=). An If
with an argument such as name=value assigns rather than tests the value.

112

JSL Building Blocks
Conditional Functions

Chapter 5
Scripting Guide

Match
You can use the Match() function to make several equality comparisons without needing to
rewrite the value to be compared. The syntax is:
Match(x, value1, result1, value2, result2, ..., resultElse)

For example, the following script recodes gender abbreviations in Big Class.jmp:
For Each Row (sex =
Match(
sex,
"F", "Female",
"M", "Male",
"Unknown");
);

The script works like this:
For Each Row(sex =

For each row in the table, sex is the column that is
recoded.

Match(

Begins the Match() loop.

);

sex,

Specifies sex as the match argument.

"F", "Female",

If the value matches ʺFʺ replace it with “Female”.

"M", "Male",

If the value matches ʺMʺ, replace it with ʺMale.

"Unknown");

If F or M are not matched, replaces the value with
ʺUnknownʺ.
Ends the loop.

This Match() example is a simplified version of the example in “If” on page 110. The
advantage of Match() is that you define the comparison value once rather than repeat it in
each condition. The disadvantage is that you cannot use expressions with operators as you can
with If; the argument sex == "F" returns an error in a Match() expression.
With more groups of conditions and results, the value of Match() becomes more apparent.
The following script would require many additional lines of code with If().
dt=open("$SAMPLE_DATA/Travel Costs.jmp");
For Each Row(Booking Day of Week =
Match(Booking Day of Week, "Sunday", "SUN", "Monday", "MON", "Tuesday",
"TUE", "Wednesday", "WED", "Thursday", "THU", "Friday", "FRI", "Saturday",
"SAT", "Not Specified");
);

Chapter 5
Scripting Guide

JSL Building Blocks
Conditional Functions

113

Be careful with the data type of the condition and result. In the preceding example, the
conditions and results are both character data. If the data types do not match, JMP
automatically changes the column’s data type. The results are not what you want.
The following script changes the column’s data type from numeric to character based on the
first cell’s data type. The first value, ʺ12ʺ, is replaced with ʺTwelveʺ, and the remaining cells are
filled with ʺOtherʺ.
dt=open("$SAMPLE_DATA/Big Class.jmp");
For Each Row(age =
Match(age, 12, "Twelve", 13, "Thirteen", 14, "Fourteen", 15, "Fifteen", 16,
"Sixteen", "Other");
);

When data consists of integers such as 1, 2, and 3, you can save even more typing by using
Choose(). See “Choose” on page 113 for more information.

Choose
The Choose() function shortens scripts even more than Match(), provided the arguments are
tested against integers. The syntax is:
Choose(expr, result1, result2, result3, ..., resultElse)

Suppose you have a data table with a column of numeric values from 1 through 7. If the first
cell contains the number 1, the following script returns x = ʺLowʺ.
x = (Choose(group,
"Low",
"Medium",
"High",
"Unknown"
);
);
Show(x);

The script works like this:
x =

Creates the x variable.

Choose(

Begins the Choose() loop.

group,

Evaluates the value of group.

"Low",

If the value of group is 1, return ʺLowʺ.

"Medium",

If the value of group is 2, return ʺMediumʺ.

"High",

If the value of group is 3, return ʺHighʺ.

114

JSL Building Blocks
Conditional Functions

Chapter 5
Scripting Guide

"Unknown"

Otherwise, return ʺUnknownʺ.

)

Ends the loop.

);

Closes the x variable.

Show(x);

Returns the value of x.

If the expression evaluates to an out‐of‐range integer (such as 7 when only 4 replacement
values are listed), the last result is returned. In the preceding example, ʺUnknownʺ is
returned.
Notice that If() and Match() require more code to achieve the same results as the Choose
function:
if(group==1, "Low", group==2, "Medium", group==3, "High", "Unknown");
match(group, 1, "Low", 2, "Medium", 3, "High", "Unknown");

Note: If the data types in the expression do not match, JMP automatically changes the
column’s data type.

Interpolate
The Interpolate() function finds the y value corresponding to a given x value between two
points (x1, y1 and x2, y2). A linear interpolation is applied to the values. You might use
Interpolate() to calculate missing values between data points.
The data points can be specified as a list:
Interpolate(x, x1, y1, x2, y2, ...)

or as matrices containing the x and y values:
Interpolate(x, xmatrix, ymatrix)

Suppose that your data set includes the height of individuals from age 20 through 25.
However, there is no data for age 23. To estimate the height for 23‐year‐olds, use interpolation.
The following example shows the value that you want to evaluate (age 23), followed by
matrices for ages (20 through 25) and heights (59 through 75).
Interpolate(23, [20 21 22 24 25], [59 62 56 69 75]);

returns:
62.5

The value 62.5 is halfway between the y values 56 and 69, just as 23 is halfway between the x
values 22 and 24.
Notes:

Chapter 5
Scripting Guide

JSL Building Blocks
Compare Incomplete or Mismatched Data

115

•

The data points in each list or matrix must create a positive slope. For example,
Interpolate(2,1,1,3,3) returns 2. However, Interpolate(2,3,3,1,1) returns a missing
value (.).

•

Interpolate is best used for continuous data, but Step() is for discrete data. See “Step”
on page 115 for details.

Step
The 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. Use Step() with discrete y values (that is, when the y
value’s corresponding x value can be only y1 or y2). However, when the y value’s
corresponding x value can fall between y1 and y2, use Interpolate().
As with Interpolate, the data points can be specified as a list:
Step(x, x1, y1, x2, y2, ...)

or as matrices containing the x and y values:
Step(x, xmatrix, ymatrix)

Suppose that your data table shows the discount percentage for purchases of $25, $50, $75,
and $100. You want to create a graph that shows the discount for a $35 purchase, which the
data table does not specify. The following example shows the value that you want to evaluate,
35, followed by matrices for purchases from $25 to $100.
Step(35, [25 50 75 100], [5 10 15 25]);

returns:
5

If the discounts were on a sliding scale (in this example, between 5 and 10, you would use
Interpolate():
Interpolate(35, [25 50 75 100], [5 10 15 25]);

returns:
7

As with Interpolate(), the data points must create a positive slope.

Compare Incomplete or Mismatched Data
Comparing data that contains missing values can return misleading results unless you specify
a condition that is always true or use functions such as Is Missing() or Zero Or Missing().
Comparisons of data with mismatched types (numeric versus character) or data in matrices
can also be confusing.

116

JSL Building Blocks
Compare Incomplete or Mismatched Data

Chapter 5
Scripting Guide

Table 5.5 shows examples of such comparisons and matrices and explanations of the results.
For a review of operators used in comparisons, see “Operators” on page 90. The sections that
follow the table provide more details about comparison and logical operators.
Note: Matrices must include the same number of columns or rows.
Table 5.5 Some Special‐Case Comparison Tests
Test

Result

Explanation

m=.; m==1

.

An equality test with a missing value returns missing.

m=.; m!=1

.

An inequality test with a missing value returns missing.

m=.; m<1; m>1; and
so on

.

A comparison with a missing value returns missing
(unless it could not possibly be true, see next).

m=.; 1/AppData/Roaming/SAS/
JMP/Addins/"

•

Macintosh: "/Users//Library/Application
Support/JMP/Addins/"

Chapter 6
Scripting Guide

Types of Data
Path Variables

127

Table 6.1 Predefined Path Variable Definitions (Continued)
Variable

Path

ALL_HOME

•
•

Windows (JMP): "/C:/ProgramData/SAS/JMP//"
Windows (JMP Pro): "/C:/ProgramData/SAS/JMPPro/
/"

DESKTOP

DOCUMENTS

•

Windows (JMP Shrinkwrap): "/C:/ProgramData/SAS/
JMPSW//"

•

Macintosh: "/Library/Application Support/JMP//"

•

Windows: "/C:/Users//Desktop/"

•

Macintosh "/Users//Desktop/"

•

Windows: "/C:/Users//Documents/"

•

Macintosh: "/Users//Documents/"

GENOMICS_HOME

"//"

HOME

•
•

Windows (JMP): "C:/Users//AppData/Roaming/
SAS/JMP//”
Windows (JMP Pro): "/C:/ProgramData/SAS/JMPPro/
/"

•

Windows (JMP Shrinkwrap): "/C:/ProgramData/SAS/
JMPSW//"

SAMPLE_APPS

SAMPLE_DATA

SAMPLE_IMAGES

•

Macintosh: "/Users//"

•

Windows: /C://Samples/Apps/"

•

Macintosh: "/Library/Application Support//Samples/Apps/"

•

Windows: ʺ/C://Samples/Data/"

•

Macintosh: "/Library/Application Support//Samples/Data/"

•

Windows: "/C://Samples/
Images/"

•

Macintosh: "/Library/Application Support//Samples/Images/"

128

Types of Data
Path Variables

Chapter 6
Scripting Guide

Table 6.1 Predefined Path Variable Definitions (Continued)
Variable

Path

SAMPLE_IMPORT_DATA

•

Windows: "/C://Samples/Import
Data/"

•

Macintosh: "/Library/Application Support//Samples/Import Data/"

SAMPLE_SCRIPTS

•

Windows: "/C://Samples/
Scripts/"

•
TEMP

•

Macintosh: "/Library/Application Support//Samples/Scripts/"
Windows: "/C:/Users//AppData/Roaming/
Temp/"

USER_APPDATA

Changes to JMP
preferences, menus, and
the Home Window are
stored here, along with
Debugger session
settings.

•

Macintosh: "/private/var/folders/.../Temporary Items/"

•

Windows (JMP): "/C:/Users//AppData/
Roaming/SAS/JMP//"

•

Windows (JMP Pro): "/C:/ProgramData/SAS/JMPPro/
/"

•

Windows (JMP Shrinkwrap): "/C:/ProgramData/SAS/
JMPSW//"

•

Macintosh: "/Users//Library/Application
Support/JMP//"

Path variable definitions are updated automatically based on the version of JMP you are
using. For example, when you run a JMP 9 script in JMP 12, the JMP 12 path variable
definitions are used.
To see the definition of any path variable, use the function Get Path Variable:
Get Path Variable("HOME");
"/C:/Users//AppData/Roaming/SAS/JMP/12/"

Note that you don’t include a dollar sign for Set Path Variable() or Get Path Variable().
But you must include the dollar sign when using the variable in a script.
Trailing Slashes
Make sure to include a trailing slash after the path variable. In the following example, the root
name "Big Class" is assigned to the dtName variable. The Open expression evaluates
$SAMPLE_DATA and the trailing slash and then appends the dtName value along with the file
extension .jmp.

Chapter 6
Scripting Guide

Types of Data
Path Variables

129

dtName = "Big Class";
dt = Open("$SAMPLE_DATA/"|| dtName ||".jmp");

The path is interpreted as:
C:/Program Files/SAS/JMP/11/Samples/Data/Big Class.jmp

Without the slash that follows $SAMPLE_DATA, the path is interpreted as:
C:/Program Files/SAS/JMP/11/Samples/DataBig Class.jmp

Create and Customize Path Variables
You can create your own path variables or override some of the built‐in variables with the Set
Path Variable(). In the following example, the path variable is called root. The variable
points to the c:/ directory.
Set Path Variable("root", "c:/");

To get the value of the new variable, use Get Path Variable().
Get Path Variable("root"); // returns "c:/"

Use your path variable as you would other variables. The following expression opens the
myimportdata.txt file in the c:/ directory.
Open("$root/myimportdata.txt")

As with getting path variables, omit the dollar sign when setting path variables.

Relative Paths
If you plan to use relative paths in variables, you must set the default directory. Then any path
not preceded by a drive letter is relative to the default directory. Here is an example:
Set Default Directory("c:/users/smith/data");

To return the value of the default directory, use Get Default Directory().
Get Default Directory(); // returns "c:/users/smith/data"

So the following expression:
Open("cleansers.jmp");

resolves as C:/users/smith/data/cleansers.jmp.

File Path Separators
In JMP, the preferred file path format is the Portable Operating System Interface (POSIX), or
UNIX, format with forward slashes (/) as separators. This means that you do not have to

130

Types of Data
Date-Time Functions and Formats

Chapter 6
Scripting Guide

identify the current operating system in scripts run on both Windows and Macintosh.
However, each host still accepts its native format for compatibility.
You can a convert file path format from Windows to POSIX (and vice versa) using Convert
File Path(). Converting from a POSIX to a Windows path might be useful when you need to
output a path to a file or to another application. The syntax is:
Convert File Path (path, , , );

For example, the following script converts a POSIX path to a Windows path:
Convert File Path("c:/users/smith", windows); //returns c:\users\smith

You can substitute a path variable (such as $HOME) for the path inside quotes.

Date-Time Functions and Formats
A date‐time value consists of any portion of a date or time. The value can be seconds
(3388594698), a complete date (such as “Wednesday, May 18, 2011”), the date and time (“05/
18/2011 8:18:18 PM”), the week number (3), and so on.
JMP lets you convert date‐time values to common formats, perform arithmetic on the values,
and manipulate the data in a number of ways.
Tip: For descriptions of all date‐time functions and their arguments, see the JSL Syntax
Reference.

Date-Time Values
Date‐time values are stored and calculated as the number of seconds since midnight, January
1, 1904. For example:
Today(); // returns 3388649872 on May 19, 2011 at 12:00:00 AM

As with Today(), the Date DMY() and Date MDY() functions also return month, day, and year
arguments as seconds. For example, if it were 12:00:00 a.m. on May 19, 2011, all of the
following statements would return the same value:
Date DMY(19,5,2011);
Date MDY(5,19,2011);
Today();
3388608000

The As Date() function takes the number of seconds and displays it as a date or duration.
•

Values that represent one year or more are returned as dates:
As Date(3388608000);
19May2011

Chapter 6
Scripting Guide

•

Types of Data
Date-Time Functions and Formats

131

Values that represent less than a year are returned as durations.
As Date(50000);
:0:13:53:20

You can use date‐time values in two ways:
•

a literal value, for example 19May2011:10:10

•

a string, for example "Thursday, May 19, 2011"

You can perform arithmetic with date‐time literals, which use the number of seconds as the
base number.
As Date( 19May2011 + 1 );
19May2011:00:00:01

Program with Date-Time Functions
Table 6.2 shows functions that convert seconds into date‐time values and date‐time values into
seconds.
Table 6.2 Date‐Time Functions
Function

Explanation

Abbrev Date(date)

Returns a string representation for the date supplied. The format
is based on your computer’s regional setting. So for the English
(United States) locale, the date is formatted like "02/29/2004".
Even if you are running JMP in English with a different locale,
the locale format is applied.

As Date(expression)

Formats a number or expression so that it shows as a date or
duration in a text window. For example, values that represent
one year or more are returned as dates.
x = As Date(8Dec2000 + inDays(2));

shows as:
10Dec2000

Values that represent less than a year are returned as durations.
As Date(50000);

shows as:
:0:13:53:20

132

Types of Data
Date-Time Functions and Formats

Chapter 6
Scripting Guide

Table 6.2 Date‐Time Functions (Continued)
Function

Explanation

Date DMY(day, month,
year)

Returns the specified date expressed as the number of seconds
since midnight, 1 January 1904. For example, the second Leap
Day of the third millennium is DateDMY(29,2,2004), which
returns 3160857600.

Date MDY(month, day,
year)

Returns the specified date expressed as the number of seconds
since midnight, 1 January 1904. For example, the second Leap
Day of the third millennium is DateMDY(2,29,2004), which
returns 3160857600.

Day Of Week(date)

Returns an integer representation for the day of the week of the
date supplied. Weeks are Sunday–Saturday.

Day Of Year(date)

Returns an integer representation for the day of the year of the
date supplied.

Day(date)

Returns an integer representation for the day of the month of the
date supplied.

Format(date,
"format")

Returns the value in the format specified in the second argument.
Most typically used for formatting datetime values from a
number of seconds to a formatted date. Format choices are those
shown in the Column Info dialog box. Also see Table 6.3 “How
JMP Interprets Two‐Digit Years” on page 137.

Hour(datetime)

Returns an integer representation for the hour part of the
date-time value supplied.

In Days(n)

These functions return the number of seconds per n minutes,
hours, days, weeks, or years. Divide by these functions to
express an interval in seconds as an interval in other units.

In Hours(n)
In Minutes(n)
In Weeks(n)
In Years(n)
Long Date(date)

Returns a string representation for the specified date. The
format is based on your computer’s regional setting. So for the
English (United States) locale, the date is formatted like
"Sunday, February 29, 2004". Even if you are running JMP in
English with a different locale, the locale format is applied.

MDYHMS(date)

Returns a string representation for the date supplied, formatted
like "2/29/2004 00:02:20 AM".

Chapter 6
Scripting Guide

Types of Data
Date-Time Functions and Formats

133

Table 6.2 Date‐Time Functions (Continued)
Function

Explanation

Minute(date-time)

Returns an integer representation for the minute part of the
date-time value supplied.

Month(date)

Returns an integer representation for the month of the date
supplied.

InFormat(string,
"format")
Parse Date(string,
"format")

Parses a string of a given format and returns datetime value
expressed as if surrounded by As Date(), returning the date in
ddMonyyyy format.

Second(date-time)

Returns an integer representation for the second part of the
date-time value supplied.

Short Date(date)

Returns a string representation for the date supplied, in the
format mm/dd/yyyy, regardless of locale (for example, "02/29/
2004").

Time Of Day(date)

Returns an integer representation for the time of day of the
date-time supplied.

Today()

Returns the current date and time expressed as the number of
seconds since midnight, 1 January 1904. No arguments are
accepted, but the parentheses are still needed.

Week Of Year(date,
)

Returns the week of the year as a date‐time value. Three rules
determine when the first week of the year begins.

Year(date)

•

With rule 1 (the default), weeks start on Sunday, with the
first Sunday of the year being week 2. Week 1 is a partial
week or empty.

•

With rule 2, the first Sunday begins with week 1, with
previous days being week 0.

•

With rule 3, the ISO‐8601 week number is returned. Weeks
start on Monday. Week 1 is the first week of the year with
four days in that year. It is possible for the first or last three
days of the year to belong to the neighboring year’s week
number.

Returns an integer representation for the year of the specified
date.

134

Types of Data
Date-Time Functions and Formats

Chapter 6
Scripting Guide

Examples of Common Date-Time Functions
You can use any function that returns seconds within a function that returns a date‐time.
For example, if today is May 19, 2011 and the time is 11:37:52 AM, Today() returns the number
of seconds, and the functions that follow show that number of seconds since the base time in
different date‐time formats:
Today()
3388649872
Short Date(Today());
"05/19/2011"
Long Date(Today());
"Thursday, May 19, 2011"
Abbrev Date(Today());
"5/19/2011"
MDYHMS(Today());
"05/19/2011 11:37:52 AM"

The date argument in parentheses can be seconds (or any function that returns seconds), or
any date‐time literal value. For example, both of the following expressions return the same
value:
Long Date(3388649872);
Long Date(19May2011);
"Thursday, May 19, 2011"

Note: Long Date() and Abbrev Date() values are formatted according to your computer’s
regional settings.
Extract Parts of Dates
You can extract parts of date values using the functions Month(), Day(), Year(), Day Of
Week(), Day Of Year(), Week Of Year(), Time Of Day, Hour(), Minute(), and Second(),
which all return integers. If today is May 24th, 2011, each of the following examples returns
the 144th day of the year:
Day of Year(Today());
Day of Year(24May2011);
Day of Year(Date MDY(5,24,2011));
144

Example
A data table column named Date contains date‐time values that are formatted as "m/d/y". You
want to create a column that shows only the time. In the following script, the second column’s
formula extracts the time of day from the Date value in the first column.

Chapter 6
Scripting Guide

Types of Data
Date-Time Functions and Formats

135

New Table( "Assembly Tests",
Add Rows( 1 ),
New Column( "Date",
Numeric, Continuous,
Format( "m/d/y" ),
Set Values( [3389083557] )
),
New Column( "Time",
Numeric, Continuous,
Formula(Format(Time Of Day( :Date ), "h:m:s"))
)
);

Figure 6.1 shows the result. Note that the time of day does not appear in the Date column,
because the Format function applies the “m/d/y” format.
Figure 6.1 Example of Extracting the Time

Rules for Determining the Week of the Year
Week of Year() returns the week of the year as a date‐time value. Three rules determine when

the first week of the year begins.
•

With rule 1 (the default), weeks start on Sunday, with the first Sunday of the year being
week 2. Week 1 is a partial week or empty.
Week Of Year(Date DMY(19,6,2013),1);
25

•

With rule 2, the first Sunday begins with week 1, with previous days being week 0.
Week Of Year(Date DMY(19,6,2013),2);
24

•

With rule 3, the ISO‐8601 week number is returned. Weeks start on Monday. Week 1 is the
first week of the year with four days in that year. It is possible for the first or last three days
of the year to belong to the neighboring year’s week number.
Week Of Year( Date DMY(19,6,2013),3);
25

Arithmetic on Dates
You can perform the usual arithmetic operations with date‐time data as with any other
numeric data. One option is simple arithmetic, such as subtracting a number from a date‐time
value.
Another option is writing a formula to perform the arithmetic.

136

Types of Data
Date-Time Functions and Formats

Chapter 6
Scripting Guide

Example
The Date column in your data table shows when a customer uses his credit card to buy gas.
You want to know how many days elapse between purchases. The following script creates a
Days elapsed column. The formula in that column subtracts the Date value in the current row
from that of the previous row.
New Table("Gas Purchases",
Add Rows(3),
New Column("Date",
Numeric, "Continuous",
Format("m/d/y"),
Set Values([3392323200 3393532800 3394828800])
),
New Column("Days elapsed",
Formula(
If(row()==1, ., // returns a missing value for the first row
(:Date[row()]-:Date[row() - 1])/in days())));
);

Figure 6.2 shows the result.
Figure 6.2 Example of Calculating Date‐Time Values

Time Intervals
The In Minutes, In Hours, In Days, In Weeks, and In Years functions are used to express
time intervals in units rather than seconds. Each of these functions returns the number of
seconds associated with a particular period of time. For example, the following expression
returns the number of weeks between now and July 4, 2012.
(Date DMY(04,07,2012)-Today())/InWeeks();
55.6559441137566

When the argument for the interval function is empty, JMP counts by 1. You can enter another
number to change the count. For example, In Years(10) converts the interval to decades. The
following expression returns the number of decades between now and December 31, 2037.
(Date DMY(31,12,2037)-Today())/InYears(10);
2.65581440286967

Chapter 6
Scripting Guide

Types of Data
Date-Time Functions and Formats

137

Two- and Four-Digit Years
JMP applies its own algorithms for interpreting and displaying datetime strings rather than
supporting operating system‐specific datetime formats. However, JMP uses the datetime
separators selected in the Region and Language control panel (Windows) or the Date & Time
preferences (Macintosh) to interpret and display dates.
Two‐digit years are interpreted according to the current system clock year and JMP rules. For
example, when the year in a script is 11, and you run the script after 1990, the year shows as
2011.
Long Date(25May11);
"Wednesday, May 25, 2011"

To avoid ambiguity, enter four‐digit years. The following expression returns 1911 (rather than
2011) as indicated:
Long Date(25May1911);
"Thursday, May 25, 1911"

Table 6.3 explains how JMP interprets two‐digit years.
Table 6.3 How JMP Interprets Two‐Digit Years
Two-Digit
Year Value

When it is Evaluated

Result

Examples

Result

00–10

before 1990 (on Windows)

19__

enter 5 in year
1979

1905

20__

enter 5 in year
1991

2005

current
century

enter 13 in year
1988

1913

enter 13 in year
2024

2013

before or during 1990 (on
Macintosh)
during or after 1990 (on
Windows)
after 1990 (on Macintosh)
11–89 (on
Windows)

any time

11–90 (on
Macintosh
)
90–99 (on
Windows)

before 2011

19__

enter 99 in year
1999

1999

91–99 (on
Macintosh
)

during or after 2011

20__

enter 99 in year
2015

2099

138

Types of Data
Date-Time Functions and Formats

Chapter 6
Scripting Guide

Note: JMP always displays four‐digit years regardless of the regional settings. If you need to
show two‐digit years, use character string functions. See the “Types of Data” chapter on
page 123.

Date-Time Values in Data Tables
Change Date-Time Input and Display Formats
In data tables, JMP can accept the input of date‐time values in one format (the input format),
store them internally as the number of seconds since the base date, and display them in a
different date‐time format. The Informat() and Format() functions give you this control.
•

Informat() takes a string date‐time value, defines the date format used in that string, and
returns the date in ddMonyyyy format.
Informat("19May2011 11:37:52 AM","ddMonyyyy h:m:s");
19May2011:11:37:52

•

Format() takes the number of seconds since the base date (or a date‐time function that

returns that number) and returns the date in the specified format.
Format(3388649872,"ddMonyyyy h:m:s");
"19May2011 11:37:52 AM"
Format(Today(),"ddMonyyyy h:m:s");
"19May2011 11:37:52 AM"

Suppose that you are entering dates into a column using the d/m/y h:m format, but you want
to see the dates in the m/d/y format. The Informat() function defines the input format, and
the Format() function defines the display format. For example,
New Table("Widget Assembly",
Add Rows(1 ),
New Column("Date",
Numeric, "Continuous",
Format("m/d/y" ),
Informat("d/m/y h:m" ),
Set Values([3126917100] )
)
);

The Format() and Informat() values are shown in the data table’s column properties
(Figure 6.3). Note that when you click in the cell to edit it, the date‐time value appears in the
input format. When you edit the value, or add a new value, the format specified in the data
table column Format list is used to display the value.

Chapter 6
Scripting Guide

Types of Data
Date-Time Functions and Formats

139

Figure 6.3 Example of Date‐Time Display and Input Values

Notes:
•

In a script that converts a column from character to numeric, specify Format() and
Informat() to prevent missing values. See “Convert Character Dates to Numeric Dates”
on page 657 in the “Common Tasks” chapter for details.

•

The date‐separator character on your computer might differ from the forward slash (/)
character shown in this book.

•

You can enter time values in 24‐hour format (military time) or with AM or PM designators.

Table 6.4 describes the formats used as arguments in date‐time functions or as data table
formats. You can also use the formats for the format argument to a Format message to a data
column. See “Set or Get Formats” on page 325 in the “Data Tables” chapter.
For descriptions of specific date‐time functions, see the JSL Syntax Reference.
Table 6.4 Date‐Time Formats
Type

Format argument

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"

140

Types of Data
Date-Time Functions and Formats

Chapter 6
Scripting Guide

Table 6.4 Date‐Time Formats (Continued)
Type

Date and time

Day number
and time

Format argument

Example

"yyyy-mm-dd"

“1999-01-02“

"yyyyQq"

1999Q1

"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:hr:m"

"34700:13:01"
":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"

"h:m"

"13:01"
"01:02 PM"

Chapter 6
Scripting Guide

Types of Data
Date-Time Functions and Formats

141

Table 6.4 Date‐Time Formats (Continued)
Type

Duration

Format argument

Example

"yyyy-mm-ddThh:mm"

1999-01-02T13:01

"yyyy-mm-ddThh:mm:ss"

1999-01-02T13:01:02

":day:hr:m"

“52:03:01”

reads fifty‐two days, three hours, and one
minute
":day:hr:m:s"

“52:03:01:30”

reads fifty‐two days, three hours, one minute,
and thirty seconds
"hr:m"

“17:37”

reads seventeen hours and thirty‐seven
minutes
"hr:m:s"

“17:37:04”

reads seventeen hours, thirty‐seven minutes,
and 4 seconds
"min:s"

“37:04”

reads thirty‐seven minutes and 4 seconds
Note: The following formats display the date‐time according to your computer’s regional
settings. They are available only for the display of dates, not for date input in a data table.
Examples are shown for the United States locale.
Abbreviated
date

"Date Abbrev"

(Display only) “01/02/1999"

Long date

"Date Long"

(Display only) "Saturday, January 02, 1999"

Locale date

“Locale Date”

(Display only) “01/02/1999"

Locale date
and time

“Locale Date Time h:m”

(Display only) “01/02/1999 13:01“ or “01/
02/1999 01:01 PM“

“Locale Date Time
h:m:s”

(Display only) “01/02/1999 13:01:02“ or
“01/02/1999 01:01:02 PM“

142

Types of Data
Currency

Chapter 6
Scripting Guide

Currency
JMP displays numbers as currency using the Format() function, which uses the following
syntax:
Format(x,"Currency", <"currency code">, );

Where:
•

x is a column or a number

•

"currency code" is an International Standards Organization (ISO) 4217 code

•

decimal is the number of decimal places

To illustrate the Format function:
Format(12345.6, "Currency", "GBP", 3);
"£12,345.600"

If you do not specify the currency code, the currency symbol is based on the computer’s
operating system locale. For example, running the following script in a Japanese operating
system formats the number with the yen symbol.
Format(12345.6, "Currency", 3);
"¥12,345.600"

If the currency code is not supported by JMP, the currency code string appears before the
number.
Format(12345.6, "Currency", "BBD", 3);
"BBD 12,345.600"

Table 6.5 lists the currencies supported in JMP.
Table 6.5 Currencies Supported in JMP
Code

Currency

Code

Currency

Code

Currency

AUD

Australian dollar

HKD

Hong Kong dollar

PHP

Philippine peso

BRL

Brazilian real

ILS

Israeli new shekel

PLN

Polish zloty

CAD

Canadian dollar

INR

Indian rupee

RUB

Russian ruble

CHF

Swiss franc

JPY

Japanese yen

SEK

Swedish krone

CNY

Chinese yuan

KRW

South Korean won

SGD

Singapore dollar

COP

Colombian peso

MXN

Mexican peso

THB

Thai baht

DKK

Danish krone

MYR

Malaysian ringgit

TWD

New Taiwan dollar

EUR

Euro

NOK

Norwegian krone

USD

US dollar

Chapter 6
Scripting Guide

Types of Data
Hexadecimal and BLOB Functions

143

Table 6.5 Currencies Supported in JMP (Continued)
Code

Currency

Code

Currency

Code

Currency

GBP

British pound

NZD

New Zealand dollar

ZAR

South African rand

Hexadecimal and BLOB Functions
JMP can also handle binary (large) objects, commonly called BLOBs. The functions below
convert between hexadecimal values, numbers, characters, and BLOBs. Some of the functions
are covered in more detail following Table 6.6.
These functions are listed in the JSL Syntax Reference.
Table 6.6 Hexadecimal and BLOB Functions
Syntax

Explanation

Hex("text")
Hex(num)
Hex(blob)

Returns the hexadecimal codes for the characters in text, number,
or blob.

Hex To
Blob(“hexstring”)

Returns a BLOB representation of the hexadecimal code
supplied as a quoted string.

Hex To
Char(“hexstring”,
encoding)

Returns a character string that corresponds to the hexadecimal
code suppled as a quoted string.

Char To Hex is an alias.

The default encoding supported for the hex code is utf‐8. You
can also specify one of these encodings: utf‐16le, utf‐16be,
us‐ascii, iso‐8859‐1, ascii‐hex, shift‐jis, and euc‐jp.
Hex to Number

Returns the number that corresponds to the hexadecimal code
suppled as a quoted string.

Char To Blob(string)
Char To Blob(string,
encoding)

Converts a string of characters into a binary (blob).

Blob To Char(blob)
Blob To Char(blob,
encoding)

The default encoding supported for the hex code is utf‐8. You
can also specify one of these encodings: utf‐8, utf‐16le, utf‐16be,
us‐ascii, iso‐8859‐1, and ascii‐hex.
Converts binary data to a Unicode string.
The default encoding supported for the hex code is utf‐8. You
can also specify one of these encodings: utf‐8, utf‐16le, utf‐16be,
us‐ascii, iso‐8859‐1, and ascii‐hex.

144

Types of Data
Hexadecimal and BLOB Functions

Chapter 6
Scripting Guide

Table 6.6 Hexadecimal and BLOB Functions (Continued)
Syntax

Explanation

Blob Peek(blob,
offset, length)

Returns a new BLOB that is a subset of the given BLOB that is
length bytes long and begins at the offset. Note that the offset is
0‐based.

Hex (string) returns the hexadecimal codes for each character in the argument. For example,
Hex("Abc")

returns
"416263"

since 41, 62, and 63 are the hexadecimal codes (in ASCII) for “A”, “b”, and “c”.
Hex to Char (string) converts hexadecimal to characters. The resulting character string
might not be valid display characters. All the characters must be in pairs, in the ranges 0‐9,
A‐Z, and a‐z. Blanks and commas are allowed, and skipped. For example,
Hex To Char (“4142”)

returns
"AB"

since 41 and 42 are the hexadecimal equivalents of “A” and “B”.
Hex and Hex To Char are inverses of each other, so
Hex To Char ( Hex("Abc") )

returns
"Abc"
Hex To Blob(string) takes a string of hexadecimal codes and converts it to a binary object.
a = Hex To Blob("6A6B6C"); Show(a);
a = Char To Blob("jkl", "ascii~hex")
Blob Peek(blob,offset,length) extracts bytes as defined by the arguments from a blob.
b = Blob Peek(a,1,2); Show(b);
b = Char To Blob("kl", "ascii~hex")
b = Blob Peek(a,0,2); Show(b);
b = Char To Blob("jk", "ascii~hex")
b = Blob Peek(a,2); Show(b);
b = Char To Blob("l", "ascii~hex")
Hex(blob) converts a blob into hexadecimal.
c = Hex(a); Show(c);
c = "6A6B6C"

Chapter 6
Scripting Guide

Types of Data
Work with Character Functions

145

d = Hex To Char(c); Show(d);
d = "jkl"
Concat(blob1,blob2) or blob1 || blob2 concatenates two blobs.
e = Hex To Blob("6D6E6F"); Show(e);
f = a||e; show(f);
e = Char To Blob("mno", "ascii~hex")
f = Char To Blob("jklmno", "ascii~hex")
length(blob) returns the number of bytes in a blob.
g = length(f); show(g);
g = 6

Note: When blobs are listed in the log, they are shown with the constructor function
Char To Blob("...").
Any hex code outside the ASCII range (space to }, or hex 20 ‐ 7D) is encoded as the
three‐character sequence [~][hexdigit][hexdigit]. For example,
h= Hex To Blob("19207D7E"); Show(h);
i = Hex(h); Show(i);
h = Char To Blob("~19 }~7E", "ascii~hex")
i = "19207D7E"
Char To Blob(string) creates a blob from a string, converting ~hex codes.
Blob To Char(blob) creates a string with ~hex codes to indicate non‐visible and non‐ASCII

codes.

Work with Character Functions
This section shows how to use some of the more complex character functions that are
described in the JSL Syntax Reference.

Concat
In the Concat function, expressions yielding names are treated like character strings, but
globals that have the name values are evaluated. The following example demonstrates that if
you have a stored name value, you need to either use Char before storing it in a global, or Name
Expr on the global name.
n = { abc };
c=n[1] || "def";
show(c);
//result is "abcdef"
m=expr(mno);

146

Types of Data
Work with Character Functions

Chapter 6
Scripting Guide

c = m || "xyz";
show(c);
//result is an error message that mno is unresolved
m = expr(mno);
c = Name Expr(m) || "xyz";
show(c);
//result is "mnoxyz"
m=char(expr(mno));
c=m || "xyz";
show(c);
//result is "mnoxyz"
Concat Items() converts a list of string expressions into a single string, with each item
separated by a delimiter. If unspecified, the delimiter is a blank. Its syntax is
resultString = Concat Items ({list of strings}, <“delimiter string”>);

For example,
a = {“ABC”, “DEF”, “HIJ”};
result = Concat Items(a, “/”);

returns
“ABC/DEF/HIJ”

Alternatively,
result = Concat Items(a);

returns
“ABC DEF HIJ”

Munger
Munger works many different ways, depending on what you specify for its arguments:
Munger(string, offset, find | length, );

Table 6.7 Munger behaviors for various types of arguments
Find, length, and replace arguments

Example

If you specify a string as the find and
specify no replace string, Munger returns
the position (after offset) of the first
occurrence find string.

Munger("the quick brown fox", 1,
"quick");

5

Chapter 6
Scripting Guide

Types of Data
Work with Character Functions

147

Table 6.7 Munger behaviors for various types of arguments (Continued)
Find, length, and replace arguments

Example

If you specify a positive integer as the
length and specify no replace string,
Munger returns the characters from offset
to offset + length.

Munger("the quick brown fox",1,5);

If you specify a string as the find and
specify a replace string, Munger replaces the
first occurrence after offset of text with
replace.

Munger("the quick brown fox", 1, "quick",
"fast");

If you specify a positive integer as the
length and specify a replace string, Munger
replaces the characters from offset to
offset + length with replace.

Munger("the quick brown fox", 1, 5,
"fast");

If you specify a positive integer as the
length, and offset + length exceeds the
length of text, Munger either returns text
from offset to the end or replaces that
portion of text with the replace string, if it
exists.

Munger("the quick brown fox",5,25);
"quick brown fox"
Munger("the quick brown fox",5,25,
"fast");

If you specify zero as the length and specify
no replace string, Munger returns a blank
string.

Munger("the quick brown fox", 1, 0);

If you specify zero as the length and specify
a replace string, the string is inserted
before the offset position.

Munger("the quick brown fox", 1, 0, "see
");

If you specify a negative integer as the
length value and specify no replace string,
Munger returns all characters from the offset
to the end of the string.

Munger("the quick brown fox", 5, -5);

If you specify a negative integer for length
and specify a replace string, Munger
replaces all characters from the offset to the
end with the replace string.

Munger("the quick brown fox", 5, -5,
"fast");

"the q"

"the fast brown fox"

"fastuick brown fox"

"the fast"

""

"see the quick brown fox"

"quick brown fox"

"the fast"

148

Types of Data
Regular Expressions

Chapter 6
Scripting Guide

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"
repeat({"A"},2)
{"A","A"}
repeat({1,2,3},2)
{1,2,3,1,2,3}

If the first argument evaluates to a number or matrix, the result is a matrix. The second
argument is the number of row repeats, and a third argument can specify the number of
column repeats. If only two arguments are specified, the number of column repeats is 1.
repeat([1 2, 3
[ 1 2 1 2 1
3 4 3 4 3
1 2 1 2 1
3 4 3 4 3
repeat(9,2,3)
[ 9 9 9,
9 9 9]

4],2,3)
2,
4,
2,
4]

The repeat function is compatible with the function of the same name in the SAS/IML
language, but is incompatible with the SAS character DATA step function, which repeats one
more time than this function.

Regular Expressions
A regular expression is a specification of a pattern frequently used to clean up or extract
pieces of data. You can search for a pattern and replace it with a different string or extract
specific parts of the string. Define the pattern in the Regex() or Regex Match() function.

Regex()
Regex() searches for a pattern within a source string and returns a string. It simply identifies
a pattern in a string or transforms a string into another string.
Regex(source, pattern, (, ), ,
);
IGNORECASE disregards case. GLOBALREPLACE repeats the match until the entire string is
processed. format is a backreference to the matched group. Regex() returns missing if the

match fails.

Chapter 6
Scripting Guide

Types of Data
Regular Expressions

149

Example of Matching a String
bus|car is the regular expression (in quotation marks because it is also a string). The

expression means match “bus” or “car”.
sentence = "I took the bus to work.";
vehicle = Regex( sentence, "bus|car" );
"bus"

Examples of Replacing a String
The third argument in Regex() is a specification of the result string. In the previous example,
the value defaults to \0, which means replace everything that was matched. The example
could also be written as follows:
sentence = "I took the bus to work.";
Regex( sentence, "bus|car", "\0" );
"bus"
\0 is a backreference to everything that was matched by the regular expression.

A more interesting variation uses parentheses to create additional backreferences.
sentence = "I took the bus to work.";
Regex( sentence, "(.*) bus (.*)", "\1 car \2" );
"I took the car to work."

The (.*) before and after bus are part of the regular expression. The parentheses create a
capturing group. The . matches any character. The * matches zero or more of the previous
expression. As a result, the first parenthesis pair matches everything before bus, and the
second parenthesis pair matches everything after bus. The third argument, \1 car \2,
reassembles the text; it leaves out bus and substitutes car.
See “Backreferences and Capturing Groups” on page 157 for more information.
Example of Global Replacement
GLOBALREPLACE changes the behavior of Regex(). If the match succeeds, the entire source
string is returned with substitutions made for each place where the pattern matches. If there
are no matches, an unchanged source string is returned.
sentence = "I took the red bus followed by the blue bus to get to work
today.";
Regex( sentence, "bus", "car", GLOBALREPLACE);
"I took the red car followed by the blue car to get to work today."

You can also use backreferences. This example starts with a different sentence.
sentence = "I took the red bus followed by the blue car to get to work
today.";
Regex(
sentence,

150

Types of Data
Regular Expressions

Chapter 6
Scripting Guide

"(\w*) (bus|car)",
"bicycle (not \2) that was \1",
GLOBALREPLACE
);
"I took the bicycle (not bus) that was red followed by the bicycle (not car)
that was blue to get to work today."

The \w* matches zero or more word characters and becomes backreference 1 because of the
parentheses. bus|car becomes backreference 2 because of the parentheses. The third
argument, bicycle (not \2) that was \1, describes how to build the substitution text for
the part of the source text that was matched.
Notice how the backreferences can be used to swap data positions. This might be useful for
swapping the position of first names and last names.

Regex Match()
Regex Match() returns an empty list with zero elements if the match fails. If the match
succeeds, the first list is the text of the entire match (backreference 0). The second list is the text
that matches backreference 1, and so on.
Regex Match(source, pattern, , );

Unlike Regex(), Regex Match() is case insensitive. Include MATCHCASE for a case‐sensitive
match. Include NULL if you want to match case but there is no replacement text.
Example of Parsing Name‐Value Pairs
The following example parses pairs of names and values.
Regex Match(
"person=Fred id=77 friend= favorite=tea",
"(\w+)=(\S*) (\w+)=(\S*) (\w+)=(\S*) (\w+)=(\S*)"
);
{"person=Fred id=77 friend= favorite=tea", "person", "Fred", "id", "77",
"friend", "", "favorite", "tea"}

The \w+ matches one or more word characters. The \S* matches zero or more characters that
are not spaces. In the resulting JSL list, the field names (person, id, friend, favorite) and
their corresponding values (fred, 77, "", tea) are separate strings.
If the first argument to Regex Match() is a variable and a third argument specifies the
replacement value, the matched text is replaced in the variable.
Comparing Regex() and Regex Match()
Regex() and Regex Match() match a pattern in a given string but return different results. To
transforms your string into another string, use Regex(). To identify the substrings that match
specific parts of the pattern, use Regex Match().

Chapter 6
Scripting Guide

Types of Data
Regular Expressions

151

This example shows the efficiency of Regex Match() compared to Regex(). The source is a list
of six strings. The goal is to extract portions of those six strings into the subject, verb, and
object columns of a data table (Figure 6.4).
Figure 6.4 Final Data Table

source = {"the cat ate the chicken", "the dog chased the cat", "did ralph like
mary", "the girl pets the dog", "these words are strange", "the cat was
chased by the dog"};
// Create the data table.
dt = New Table( "English 101",
New Column( "subject", character ),
New Column( "verb", character ),
New Column( "object", character )
);
// Iterate through the strings in the list.
For( i = 1, i <= N Items( source ), i++,
// Assign the result of each match to matchList.
matchList = Regex Match(
source[i],
// Scan each string. Match zero or more characters
// and one item in each group.
".*?(cat|dog|ralph|girl).*?(ate|chased|like|pets).*?(chicken|cat|mary|dog)"
);
// If matchList has zero items (string 5), don’t add a row
// to the table. Put each matched string in separate
// data table cells.
If( N Items( matchList ) > 0,
dt << Add Rows( 1 );
dt:subject = matchList[2]; // Match the first open parenthesis.
dt:verb = matchList[3]; // Match the second open parenthesis.
dt:object = matchList[4]; // Match the third open parenthesis.
);
);

152

Types of Data
Regular Expressions

Chapter 6
Scripting Guide

Regex Match() returns {"the cat was chased by the dog", "cat", "chased", "dog"} in a
single try with each answer in a separate string. Compare this example to a similar one using
Regex(), which returns one answer at a time and builds the final string using backreferences.
For( i = 1, i <= N Items( source ), i++,
s = Regex( source[i],
".*?(cat|dog|ralph|girl).*?(ate|chased|like|pets).*?(chicken|cat|mary|dog)
", "\1"); // Match an item in the first group.
v = Regex( source[i],
".*?(cat|dog|ralph|girl).*?(ate|chased|like|pets).*?(chicken|cat|mary|dog)
", "\2" ); // Match an item in the second group.
o = Regex( source[i],
".*?(cat|dog|ralph|girl).*?(ate|chased|like|pets).*?(chicken|cat|mary|dog)
", "\3" ); // Match an item in the third group.
If( !Is Missing( s ) & !Is Missing( v ) & !Is Missing( o ),
dt << Add Rows( 1 );
dt:subject = s; // Return the match for \1.
dt:verb = v; // Return the match for \2.
dt:object = o; // Return the match for \3.
);
);

Backreferences are discussed in “Backreferences and Capturing Groups” on page 157.

Special Characters in Regular Expressions
Special characters are commonly used in regular expressions. The period is a special character
that matches one instance of the specified character. It must be escaped with a backslash to be
interpreted as a period. In the following expression, the period is replaced with an
exclamation point.
Regex( "Bicycling makes traveling to work fun.", "\.", "!", GLOBALREPLACE );
"Bicycling makes traveling to work fun!"

Table 6.8 describes the special characters and provides examples.
Table 6.8 Special Characters in Regular Expressions
\

•

Precedes a literal character.
<\/a> interprets the forward slash literally in the end HTML anchor tag.

•

Precedes an escape sequence.
\n matches a newline character.

^

Matches the beginning of a string, not including the newline character.
^apple matches “apple” at the beginning of a string.

Chapter 6
Scripting Guide

Types of Data
Regular Expressions

153

Table 6.8 Special Characters in Regular Expressions (Continued)
$

Matches the end of a string, not including the newline character.
apple$ matches “apple” at the end of a string.

.

Matches any single character including a newline character.
.apple matches any single character and then “apple”.

|

Represents a logical OR to separate alternative values.
(apple|orange|banana) matches “apple”, “orange”, or “banana”.

?

Matches zero or one instance.
apple (pie)? matches one or more instances of “pie”.

*

Matches zero or more instances.

+

Matches one or more instances.

( )

Encloses a sub‐expression.
(apple|orange|banana) matches “apple”, “orange”, or “banana”.
^(\w+) matches the beginning of a line and then one or more word

characters.
[ ]

Encloses an expression that matches set of characters.
[\s] matches a whitespace character or a digit.
[a-z0-9] matches “a” through “z” and numbers “0” through “9”.

{ }

Encloses an expression that represents repetition.
apple{3} repeats three times.
apple{3,} repeats at least three times as many times as possible.
apple{3, 10} repeats three times but no more than 10 times.

Append a question mark to indicate repeating as few times as possible. For
example, apple{3,}? repeats at least three times as few times as possible.

Escaped Characters in Regular Expressions
The backslash in a regular expression precedes a literal character. You also escape certain
letters that represent common character classes, such as \w for a word character or \s for a
space. The following example matches word characters (alphanumeric and underscores) and
spaces.

154

Types of Data
Regular Expressions

Chapter 6
Scripting Guide

Regex(
"Are you there, Alice?, asked Jerry.", // source
"(here|there).+(\w+).+(said|asked)(\s)(\w+)\." ); // regular expression
"there, Alice?, asked Jerry."
(here|there).+

Matches “there”, a comma, and a space.

(\w+)

Matches “Alice”.

.+

Matches “?, “.

(said|asked)(\s)

Matches “asked” followed by a space. Without the space, the
match would end here; “asked” is followed by a space in the
source string.

(\w+)\.

Matches “Jerry” and a period.

Table 6.9 describes the escaped characters supported in JMP. \C, \G, \X, and \z are not
supported.
J

Table 6.9 Escaped Characters
\A

start of a string

\b

word boundary. The zero‐length string between \w and \W or \W and
\w.

\B

not at a word boundary

\cX

ASCII control character

\d

single digit [0-9]

\D

single character that is NOT a digit [^0-9]

\l

match a single lowercase letter [a-z]

\L

single character that is not lowercase [^a-z]

\s

single whitespace character

\S

single character that is NOT white space

\u

single uppercase character [A-Z]

\U

single character that is not uppercase [^A-Z]

\w

word character [a-zA-Z0-9_]

\W

single character that is NOT a word character [^a-zA-Z0-9_]

Chapter 6
Scripting Guide

Types of Data
Regular Expressions

155

Table 6.9 Escaped Characters (Continued)
\x00-\xFF

hexadecimal character

\x{0000}-\x{FFFF}

Unicode code point

\Z

end of a string before the line break

Greedy and Reluctant Regular Expressions
The ?, *, and + operators are greedy by default. They match as many of the preceding
character as possible. The ? operator makes them reluctant; ?? matches 0, then 1 if needed; +?
matches 1 and then additional characters; *? matches 0 and then additional characters.
The following example starts at the letter n and compares it to the first \d (digits) in the
pattern. No digit matches. Because the pattern does not begin with ^ (start of line), the
matcher advances to u. The process repeats until the 3 matches the first \d and the 2 matches
the second \d.
Regex( "number=32.5", "\d\d" );
"32"

Change the pattern to use the greedy + (match one or more).
Regex( "number=324.5", "\d+" );
"324"

The preceding example begins much the same, but as soon as the 3 is found and the \d
matches, the + greedily matches the 2 and the 4.
Usually, the greedy behavior makes pattern matching faster because the string is consumed
sooner. Sometimes a reluctant behavior is better. Adding the ? after the * or + changes them
from greedy to reluctant.
Regex( "number=324.5", "\d+?" );
"3"

Here, + requires at least one match of a digit character, but ? changes it from “as many as
possible” to “as few as possible”. It stopped after the 3 because the pattern was satisfied.
Compare the following results.
Greedy:
Regex( "number=324.5", "(\d+)(\d+)\.", "first=\1 second=\2" );
"first=32 second=4"

Reluctant:
Regex( "number=324.5", "(\d+?)(\d+?)\.", "first=\1 second=\2" );
"first=3 second=24"

156

Types of Data
Regular Expressions

Chapter 6
Scripting Guide

In the greedy example above, the matcher greedily matched 3, 2, and 4 for the first \d+. The
matcher then had to give back the 4 so that the second \d+ could match something. The
reluctant example followed a different path to get a different answer. Initially, the second
value was 2, but the pattern could not match the period to the 4, so the second \d+? reluctantly
matched the 4 as well.
Use the Reluctant Match for Speed
The greedy and reluctant matches usually produce the same result but not always. See the
previous section. One reason you might need the reluctant match is for speed. Suppose that
you have a million‐character string that begins “The quick fox…” and you want to find the
word before “fox”. You might write the following expression and expect \1 to contain
“quick”.
The (.+) fox
\1 might contain “quick” eventually, after the .* grabs the million characters to the end of the

string and then gives them up, one at a time, until “fox” is found. If there is more than one
“fox”, it will be the last fox, not this one. To speed it up and make sure we get the first fox, add
the ? operator.
The (.+?) fox

The ? advances one character at a time to get past “quick” and find the first “fox”. This
method is much faster than going too far.
Typically, the + or * operator is applied to a more restrictive expression such as \d* to match a
run of digits, and greedy is faster than reluctant.
Aside from the multiple fox possibility, greedy and reluctant eventually get the same answer.
Using the right operator speeds up the match. The right one might be greedy, or it might be
reluctant. It depends on what is being matched.
The greedy .* finds the last fox after backing up.
Regex(
"The quick fox saw another fox eating grapes",
"The (.*) fox",
"\1"
);
"quick fox saw another"

The reluctant .*? stops on the first fox.
Regex(
"The quick fox saw another fox eating grapes",
"The (.*?) fox",
"\1"
);
"quick"

Chapter 6
Scripting Guide

Types of Data
Regular Expressions

157

The greedy .* has to back up a lot. There is no second fox.
Regex(
"The quick fox saw another animal eating grapes",
"The (.*) fox",
"\1"
);
"quick"

The greedy word character match is an even better choice for this problem.
Regex(
"The quick fox saw another fox eating grapes",
"The (\w*) fox",
"\1"
);
"quick"

Backreferences and Capturing Groups
A regular expression can consist of patterns grouped in parentheses, also known as capturing
groups. In ([a-zA-Z])\s([0-9]), ([a-zA-Z]) is the first capturing group; ([0-9]) is the
second capturing group.
Use a backreference to replace the pattern matched by a capturing group. In Perl, these groups
are represented by the special variables $1, $2, $3, and so on. ($1 indicates text matched by the
first parenthetical group.) In JMP, use a backslash followed by the group number (\1, \2, \3).
The following example includes a third argument that specifies the replacement text and
backreferences.
Regex(
"
Are you there, Alice?, asked Jerry.", // source
" (here|there).+ (\w+).+(said|asked) (\w+)\.", // regular expression
" I am \1, \4, replied \2." ); // optional format argument
" I am there, Jerry, replied Alice."
" I am \1,

Creates the text “I am”, a space, “there”, and then the first
matched pattern, “there”.

\4,

Creates the text “Jerry” with the fourth matched pattern
(\w+).

replied \2."

Creates the text “replied” and a space. Matches “Alice.” with
the second matched pattern (\w+).

158

Types of Data
Pattern Matching

Chapter 6
Scripting Guide

Lookaround Assertions
Lookaround assertions check for a pattern but do not return that pattern in the results.
Lookaheads look forward for a pattern. Lookbehinds look back for a pattern.
Negative Lookahead Example
Negative lookaheads check for the absence of a pattern ahead of a specific pattern. ?!
indicates a negative lookahead. The following expression matches a comma not followed by a
number or space and replaces the pattern with a comma and space:
Regex( "one,two 1,234 cat,dog,duck fish, and chips,to go", ",(?!\d|\s)", ",
",GLOBALREPLACE);
"one, two 1,234 cat, dog, duck fish, and chips, to go"

Positive Lookahead Example
Positive lookaheads check for the presence of a pattern ahead of a specific pattern. ?= indicates
a positive lookahead. The following expression has the same result as the preceding negative
lookahead but matches a comma followed by any lowercase character:
Regex( "one,two 1,234 cat,dog,duck fish, and chips,to go", ",(?=[a-z])", ",
",GLOBALREPLACE);
"one, two 1,234 cat, dog, duck fish, and chips, to go"

Positive Lookbehind Example
In this example, the positive lookbehind regular expression matches the “ssn=” or “salary=”
keywords without including the keyword in the matched text. The matched text is the string
of characters that consists of zero or more dollar signs, digits, and hyphens.
data = "name=bill salary=$5 ssn=123-45-6789 age=13,name=mary salary=$6
ssn=987-65-4321 age=14";
redacted = Regex(data, "(?<=(ssn=)|(salary=))[$\d-]*", "###", GLOBALREPLACE);
"name=bill salary=### ssn=### age=13,name=mary salary=### ssn=### age=14"

Here is another way to get the same result using a backreference substitution.
((ssn=)|(salary=)) is the capturing group. "\1" is the backreference to that group.
data = "name=bill salary=$5 ssn=123-45-6789 age=13,name=mary salary=$6
ssn=987-65-4321 age=14";
redacted = Regex(data, "((ssn=)|(salary=))[$\d-]*", "\1###", GLOBALREPLACE);
"name=bill salary=### ssn=### age=13,name=mary salary=### ssn=### age=14"

Backreferences are discussed in “Backreferences and Capturing Groups” on page 157.

Pattern Matching
Pattern matching in JSL is a flexible method for searching and manipulating strings.

Chapter 6
Scripting Guide

Types of Data
Pattern Matching

159

You define and use pattern variables just like any JMP variable:
i
a
t
p

=
=
=
=

3; // a numeric variable
"Ralph"; // a character variable
textbox("Madge"); // a display box variable
( "this" | "that" ) + patSpan(" ")
+ ( "car" | "bus" ); // a pattern variable

When the above statement executes, p is assigned a pattern value. The pattern value can be
used either to construct another pattern or to perform a pattern match. The patSpan function
returns a pattern that matches a span of characters specified in the argument;
patSpan("0123456789") matches runs of digits.
p2 = "Take " + p + "."; // using p to build another pattern
if( patMatch( "Take this bus.", p2 ), print("matches"),
print("no match") ); // performing a match

Sometime all you need to know is that the pattern matched the source text, as above. Other
times, you might want to know what matched; for example, was it a bus or a car?
p = ("this" | "that") + Pat Span( " " ) + ("car" | "bus") >?
vehicleType; // conditional assignment ONLY if pattern matches
If( Pat Match( "Take this bus.", p ),
Show( vehicleType ),
Print( "no match" )
); // do not use vehicleType in the ELSE because it is not set

You could pre‐load vehicleType with a default value if you do not want to check the outcome
of the match with an if. The >? conditional assignment operator has two arguments, the first
being a pattern and the second a JSL variable. >? constructs a pattern that matches the pattern
(first argument) and stores the result of the match in the JSL variable (second argument) after
the pattern succeeds. Similarly, >> does not wait for the pattern to succeed. As soon (and as
often) as the >> pattern matches, the assignment is performed.
findDelimString = patLen(3)>>beginDelim + patArb()>?middlePart +
expr(beginDelim);
testString = "SomeoneSawTheQuickBrownFoxJumpOverTheLazyDog'sBack";
rc = PatMatch( testString, findDelimString, "<<<" || middlePart || ">>>" );
show( rc, beginDelim, middlePart, testString );

The above example shows a third argument in the patMatch function: the replacement string.
In this case, the replacement is formed from a concatenation (|| operator) of three strings. One
of the three strings, middlePart, was extracted from the testString by >? because the
replacement cannot occur unless the pattern match succeeds (rc == 1).
Look at the pattern assigned to findDelimString. It is a concatenation of 3 patterns. The first
is a >> operator that matches 3 characters and assigns them to beginDelim. The second is a >?
operator that matches an arbitrary number of characters and, when the entire match succeeds,
assigns them to middlePart. The last is an unevaluated expression, consisting of whatever

160

Types of Data
Pattern Matching

Chapter 6
Scripting Guide

string is in beginDelim at the time the pattern is executing, not at the time the pattern is built.
Just like expr(), the evaluation of its argument is postponed. That makes the pattern hunt for
two identical three letter delimiters of the middle part.
Other pattern functions might be faster and represent the problem that you are trying to solve
better than writing a lot of alternatives; for example, "a"|"b"|"c" is the same as
patAny("abc"). The equivalent example for patNotAny("abc") is much harder. Similar to
patSpan (above), patBreak("0123456789") matches up to, but not including, the first number.
Here is a pattern that matches numbers with decimals and exponents and signs. It also
matches some degenerate cases with no digits; look at the pattern assigned to digits.
digits = patSpan("0123456789") | "";
number = ( patAny("+-") | "" ) >? signPart +
( digits ) >? wholePart +
( "." + digits | "" ) >? fractionPart +
( patAny("eEdD") + ( patAny("+-") | "" ) + digits | "" ) >?
exponentPart;
if( patMatch( "-123.456e-78", number ), show( signPart, wholePart,
fractionPart, exponentPart ) );

Parsing Strings in Fixed Fields
Sometimes data is in fixed fields. The patTab, patRTab, patLen, patPos, and patRPos functions
make it easy to split out the fields in a fixed field string. PatTab and patRTab work from the
left and right end of the string and take a number as their argument. They succeed by
matching forward to the specified tab position. For example:
p = patPos(10) + patTab(15);
PatPos(10) matches the null string if it is in position 10. So at match time, the matcher works
its way forward to position 10, then patTab(15) matches text from the current position (10)
forward to position 15. This pattern is equivalent to patPos(10)+patLen(5). Another example:
p = patPos(0) + patRTab(0);

This example matches the entire string, from 0 characters from the start to 0 characters from
the end. the patRem() function takes no argument and is shorthand for patRTab(0); it means
the remainder of the string. Pattern matching can also be anchored to the beginning of the
string like this:
patMatch( "now is the time", patLen(15) + patRPos(0), NULL, ANCHOR );

The above pattern uses NULL rather than a replacement value, and ANCHOR as an option. Both
are uppercase, as shown. NULL means that no replacement is done. ANCHOR means that the
match is anchored to the beginning of the string. The default value is UNANCHORED.
Patterns can be built up like this, but this is not recursive:

Chapter 6
Scripting Guide

Types of Data
Pattern Matching

161

p = "a" | "b"; // matches one character
p = p + p; // two characters
p = p + p; // four characters
patMatch( "babb", patPos(0) + p + patRPos(0) );

A recursive pattern refers to its current definition using expr():
p = "<" + expr(p) + "*" + expr(p) + ">" | "x";
patMatch( "<>*x>", patPos(0) + p + patRPos(0) );

Remember, expr() is the procrastination operator; when the pattern is assigned to the variable
p, expr() delays evaluating its argument (p) until later. In the next statement, patMatch
performs the pattern match operation, and each time it encounters expr(), it looks for the
current value of the argument. In this example, the value does not change during the match).
So, if p is defined in terms of itself, how can this possibly work?
p consists of two alternatives. The right hand choice is easy: a single letter x. The left side is
harder:  . Each p could be a single letter x, since that is one of the choices p could match,
or it could be . The last few example have used patPos(0) + ... + patRPos(0) to make
sure the pattern matches the entire source text. Sometimes this is what you want, and
sometimes you would rather the pattern match a subtext. If you are experimenting with these
examples by changing the source text, you probably want to match the entire string to easily
tell what was matched. The result from patMatch is 0 or 1.

This example uses “Left” recursion:
x =

expr(x) + "a" | "b"; // + binds tighter than |

If the pattern is used in FULLSCAN mode, it eventually uses up all memory as it expands. By
default, the patMatch function does not use FULLSCAN, and makes some assumptions that
allow the recursion to stop and the match to succeed. The pattern matches either a “b”, or
anything the pattern matches followed by an “a”.
rc = patMatch( "baaaaa", x );

Patterns and Case
Unlike regular expressions, pattern matching is case insensitive. To force case sensitivity, you
can add the named argument MATCHCASE to either Pat Match or Regex Match. For
example:
string = "abcABC";
result = Regex Match( string, Pat Regex( "[aBc]+" ) );
Show( string, result );
string = "abcABC"
result = {"abcABC"}
result = Regex Match( string, Pat Regex( "[cba]+" ), NULL, MATCHCASE );

162

Types of Data
Pattern Matching
Show( string, result );
string = "abcABC"
result = {"abc"}

Chapter 6
Scripting Guide

Chapter 7
Data Structures
Working with Collections of Data
JSL provides these basic data structures that can hold a variety of data in a single variable:
•

A list holds a number of other values, including nested lists and expressions.

•

A matrix is a row‐by‐column table of numbers.

•

An associative array maps keys to values, which can be almost any other type of data.

Contents
Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Evaluate Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Assignments with Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Perform Operations in Lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Find the Number of Items in a List. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Subscripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Locate Items in a List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
List Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Iterate through a List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Concatenate Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Construct Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Subscripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
Inquiry Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Comparisons, Range Checks, and Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Numeric Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Transpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Matrices and Data Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Matrices and Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Loc Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Ranking and Sorting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Special Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Inverse Matrices and Linear Systems. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Decompositions and Normalizations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Build Your Own Matrix Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Statistical Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Associative Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

Chapter 7
Scripting Guide

Data Structures
Lists

165

Lists
Lists are containers to store items, such as the following:
•

numbers

•

variables

•

character strings

•

expressions (for example, assignments or function calls)

•

matrices

•

nested lists

Create a list in one of the following ways:
•

use the List function

•

use { } curly braces

Examples
Use the List() function or curly braces to create a list that includes numbers and variables:
x = List(1, 2, b);
x = {1, 2, b};

A list can contain text strings, other lists, and function calls:
{"Red", "Green", "Blue", {1, "true"}, sqrt(2)};

You can place a variable into a list and assign it a value at the same time:
x = {a=1, b=2};

Evaluate Lists
When you run a script that contains a list, a copy of the list is returned. The items inside the
list are not evaluated.
b = 7;
x = {1, 2, b, Sqrt(3)};
Show(x);
x = {1, 2, b, Sqrt(3)};

To evaluate items in a list, use the Eval List function.
b = 7;
x = {1, 2, b, Sqrt(3)};
c = Eval List(x);
{1, 2, 7, 1.73205080756888}

166

Data Structures
Lists

Chapter 7
Scripting Guide

Assignments with Lists
Create a list to assign values to variables.
Examples
{a, b, c} = {1, 2, 3}; // assigns 1 to a, 2 to b, and 3 to c
{a, b, c}--; // decrements a, b, and c
{{a}, {b, c}}++; // increments a, b, and c by 1
mylist = {1, log(2), e()^pi(), height[40]}; // stores the expressions

Perform Operations in Lists
In lists, you can perform operations.
a = {{1, 2}, 3, {4, 5}};
b = {{10, 20}, 30, {40, 50}};
c = a + b;
c = {{11, 22}, 33, {44, 55}}

Find the Number of Items in a List
To determine the number of items in a list, use the N Items() function.
x = {1, 2, y, Sqrt(3), {a, b, 3}};
N = N Items(x);
Show(n);
n = 5;

Subscripts
Subscripts extract specified items from a list. Use a list as a subscript to return multiple items
from a list.
Note: JSL starts counting from 1, so the first element in a list is [1], not [0] as in some other
languages.
Examples
List a contains four items.
a = {"bob", 4, [1,2,3], {x,y,z}};
Show( a[1] );
a[1] = "bob";
Show( a[{1,3}] );
a[{1, 3}] = {"bob", [1, 2, 3]};
a[2] = 5; // assigns 5 to the second list item

Chapter 7
Scripting Guide

Data Structures
Lists

167

You can also use subscripts to select or change items in a list:
Show( a );
a = {"bob", 5, [1, 2, 3], {x, y, z}};
c = {1, 2, 3};
c[{1, 2}] = {4, 4};
// c[{1, 2}] = 4 produces the same result
Show( c );
c = {4, 4, 3};

When you have assignments or functions in a list, you can use a quoted name for the subscript
to extract the value.
x={sqrt(4), log(3)};
xx={a=1, b=3, c=5};
x["sqrt"];
4
xx["b"];
3

The name must be in quotation marks, or else JMP tries to evaluate it and use its value. The
following example shows the values of the second item in the list, rather than the value of a in
the list.
a = 2;
Show(xx[a]);
xx[a] = b = 3;

Note the following:
•

Multiple left‐side subscripts (for example, a[i][j] = value where a contains a list of
things that are subscriptable) are allowed in the following circumstances:
‒ Each level except the outermost level must be a list. So, in the example above, a must be
a list but a[i] can be anything subscriptable.
‒ Each subscript except the last must be a number. So, in the example above, i must be a
number, but j could be a matrix or list of indices.

•

Subscripting can be done to any level of nesting, such as the following:
a[i][j][k][l][m][n] = 99;

Locate Items in a List
Use the Loc() function or the Contains() function to find values in a list:
Loc(list, value)
Contains(list, value)
Loc() and Contains() return the positions of the values. Loc() returns the results in a matrix,
and Contains() returns the results as a number.

168

Data Structures
Lists

Chapter 7
Scripting Guide

Note the following:
•

The Loc function returns each occurrence of a repeated value. Contains() returns only the
first occurrence of a repeated value.

•

If the value is not found, the Loc function returns an empty matrix and Contains() returns
a zero.

•

To assess whether an item is in a list, use Loc() and Contains() with >0. A returned value
of zero means that the item is not in the list. A returned value of 1 means that the item is in
the list at least once.

Note: For details about matrix manipulation and a description of the equivalent Loc()
command for matrices, see “Matrices” on page 173.
Examples
nameList = {“Katie”, “Louise”, “Jane”, “Jane”};
numList = {2, 4, 6, 8, 8};

Search for the value "Katie" in the nameList:
Loc(nameList, “Katie”);
[1]
Contains(nameList, "Katie");
1

Search for the value "Erin" in the nameList:
Loc(nameList, “Erin”);
[]
Contains(nameList, "Erin");
0

Search for the number 8 in the numList:
Loc(numList, 8);
[4, 5]
Contains(numList, 8);
4

Find out if the number 5 exists in the numList:
NRow(Loc(numList, 5)) >0;
0
Contains(numList, 5) >0;
0

List Operators
Table 7.1 describes the list operators and their syntax.

Chapter 7
Scripting Guide

Data Structures
Lists

169

Table 7.1 List Operators
Operator and Function

=
+=
-=
*=
/=
++
--

Syntax

Explanation

As List()

As List(matrix)

Returns the matrix as a list. A matrix
with multiple columns is returned as
a list of lists, one list per row.

Assign()
Add To()
SubtractTo()
MultiplyTo()
DivideTo()
Post Increment()
Post Decrement()

{list} = {list}
{list} += value
{list} -= {list}
...

If the target of an assignment
operator is a list and the value to be
assigned is a list, then it assigns item
by item. The ultimate values in the
left list must be L‐values (in other
words, names capable of being
assigned values).
Notes:
•

If you want to test equality of
lists, use ==, not =.

•

JMP does not have a
pre‐decrement operator. Use the
SubtractTo() operator instead
(-=).

||=

Concat To()

Concat To(list1,
list2, ...)

Inserts the second and subsequent
lists at the end of the first list.

||

Concat()

Concat(list1, list2,
...);

Returns a copy of the first list with
any additional lists inserted at after
it.

Eval List()

Eval List(list)

Returns a list of the evaluated
expressions inside list. See “Evaluate
Lists” on page 165.

Insert Into()

Insert Into(list, x,
)

Inserts a new item (x) into the list at
the given position (i). If i is not
given, the item is added to the end of
the list. This function does change
the original list.

170

Data Structures
Lists

Chapter 7
Scripting Guide

Table 7.1 List Operators (Continued)
Operator and Function

{ }

Syntax

Explanation

Insert()

list = Insert(list,
x, )

Returns a copy of the list with a
new item (x) inserted into the list at
the given position (i). If i is not
given, the item is added to the end of
the list. This function does not
change the original list.

Is List()

Is List(arg)

Returns true (1) if arg is a classical
list (in other words, 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.

List

List(a, b, c)
{a, b, c}

Constructs a list from a set of items.
An item can be any expression,
including other lists. Items must be
separated by commas. Text 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.

Remove From()

Remove From(list,
, )

Deletes n items from the list,
starting from the indicated position
(i). If n is omitted, the item at i is
deleted. If n and i are omitted, the
item at the end is removed. This
function does change the original list.

Remove()

Remove(list, ,
)

Returns a copy of the list with the n
items deleted, starting from the
indicated position (i). If n is omitted,
the item at i is deleted. If n and i are
omitted, the item at the end is
removed. This function does not
change the original list.

Chapter 7
Scripting Guide

Data Structures
Lists

171

Table 7.1 List Operators (Continued)
Operator and Function

[ ]

Syntax

Explanation

Reverse Into()

Reverse Into(list)

Reverses the order of the items in the
list. This function does change the
original list.

Reverse()

Reverse(list)

Returns a copy of the list with the
items in reverse order. This function
does not change the original list.

Shift Into()

Shift Into(list, )

Shifts n items from the front of the
list to the end of the list. If n is
omitted, the first item is moved to the
end of the list. This function does
change the original list.

Shift()

Shift(list, )

Returns a copy of the list with n
items shifted from the front of the list
to the end of the list. If n is omitted,
the first item is moved to the end of
the list. This function does not
change the original list.

Sort Ascending()

Sort Ascending(list)

Returns a copy of the list sorted in
ascending order. This function does
not change the original list.

Sort
Descending()

Sort Descending(list)

Returns a copy of the list sorted in
descending order. This function does
not change the original list.

Sort List Into()

Sort List Into(list)

Sorts the list in ascending order.
This function does change the
original list.

Sort List()

Sort List(list)

Returns a copy of the list sorted in
ascending order. This function does
not change the original list.

Subscript()

list[i]
x = list[i]
list[i] = value
a[b, c]
Subscript(a, b, c)

Subscripts for lists extract the ith
item from the list. Subscripts can in
turn be lists or matrices.

172

Data Structures
Lists

Chapter 7
Scripting Guide

Table 7.1 List Operators (Continued)
Operator and Function
Substitute()

Substitute
Into()

Syntax

Explanation

Substitute(list,
pattExpr1,
replExpr1, ...)

Returns a copy of a list or expression,
replacing instances of each pattern
expression with the corresponding
replacement expression.

Substitute Into(list,

Changes a list or expression,
replacing instances of each pattern
expression with the corresponding
replacement expression. Note: The
list or expression must be a
variable.

pattExpr1,
replExpr1, ...)

Iterate through a List
Iterate through a list to do something with each value or look for a particular value. The
following script looks at each item in the list. If the item in the list is less than or equal to 10, it
is replaced with its square.
x = {2, 12, 8, 5, 18, 25};
n = N Items (x);
for (i=1, i<=n, i++,
if (x[i]<=10, x[i]=x[i]^2)
);
Show (x)
x = {4, 12, 64, 25, 18, 25};

You can use Loc() to locate the items in the new list that are equal to 25:
Loc (x,25)
[4, 6] // The fourth and sixth items in the list are equal to 25.

Concatenate Lists
Join two or more lists into one list with Concat() or the || operator.
The following example uses Concat() to join lists a and b:
a = {1, 2};
b = {7, 8, 9};
Concat( a, b );
{1, 2, 7, 8, 9}

The following example joins the same lists using the || operator:
{1, 2} || {7, 8, 9}

Chapter 7
Scripting Guide

Data Structures
Matrices

173

{1, 2, 7, 8, 9}

Lists of different types can be concatenated (for example, lists that contain character strings
and numbers).
d = {"apples", "bananas"};
e = {"oranges", "grapes"};
f = {1, 2, 3};
Concat( d, e, f);
{"apples", "bananas", "oranges", "grapes", 1, 2, 3}

Matrices
A matrix is a rectangular array of numbers that are arranged in rows and columns. Use
matrices to store numbers and perform calculations on those numbers using matrix algebra.
Note the following for this section:
•

Matrices are represented with an uppercase bold variable (for example, A).

•

A matrix with one row or one column is a vector (or more specifically, a row vector or a
column vector respectively).

•

For clarity, we represent matrices that are vectors with lowercase bold letters (such as x).

•

A scalar is a numeric value that is not in a matrix.

Construct Matrices
Note the following when creating matrices:
•

Place matrix literals in square brackets. [...]

•

Matrix values can contain decimal points, can be positive or negative, and can be in
scientific notation.

•

Separate items across a column with blank spaces. You can use any number of blank
spaces.

•

Separate rows with a comma.

For constructing more advanced matrices, see “Special Matrices” on page 188.
Examples
Create matrix A with 3 rows and 2 columns:
A = [1 2, 3 4, 5 6];

R is a row vector and C is a column vector:
R = [10 12 14];

174

Data Structures
Matrices

Chapter 7
Scripting Guide

C = [11, 13, 15];

B is a 1‐by‐1 matrix, or a matrix with one row and one column:
B = [20];

E is an empty matrix:
E = [];

Specifying the number of rows and columns in an empty matrix is optional. JMP creates the
matrix as necessary.
A script can return an empty matrix. In Big Class.jmp, the following expression looks for rows
in which age equals 8, finds none, and returns an empty matrix:
a = dt << Get Rows Where( age == 8 );
Show( a );
a = [](0,1);

Construct Matrices from Lists
If you want to convert lists into a matrix, use the Matrix() function. A single list is converted
into a column vector. Two or more lists are converted into rows.
Create a column vector from a single list:
A = matrix({1,2,3});
[1,2,3]

Create a matrix from a list of lists. Each list is a row in the matrix.
A = matrix({{1,2,3}, {4,5,6}, {7,8,9}});
[1 2 3,
4 5 6,
7 8 9]

Construct Matrices from Expressions
To construct matrices from expressions, use Matrix(). Elements must be expressions that
resolve to numbers.
A = matrix({4*5, 8^2, sqrt(9)});
[20, 64, 3]

Subscripts
Use the subscript operator ([ ]) to pick out elements or submatrices from matrices. The
Subscript() function is usually written as a bracket notation after the matrix to be
subscripted, with arguments for rows and columns.

Chapter 7
Scripting Guide

Data Structures
Matrices

175

Single Element
The expression A[i,j] extracts the element in row i, column j, returning a scalar number. The
equivalent functional form is Subscript(A,i,j).
P=[1 2 3, 4 5 6, 7 8 9];
P[2,3]; // returns 6
Subscript(P,2,3); // returns 6

Assign the value that is in the third row and the first column in the matrix A (which is 5) to the
variable test.
A=[1 2, 3 4, 5 6];
test = A[3,1];
Show(test);
test = 5;

Matrix or List Subscripts
To extract a sub‐matrix, use matrix or list subscripts. The result is a matrix of the selected rows
and columns. The following expressions select the 2nd and 3rd rows with the 2nd and 1st
columns.
P=[1 2 3, 4 5 6, 7 8 9];
P[[2 3],[1 3]]; // matrix subscripts
P[{2,3},{1,3}]; // list subscripts

Both of these methods provide the following output:
[4 6,
7 9]

Single Subscripts
A single subscript addresses matrices as if all the rows were connected end‐to‐end in a single
row. This makes the double subscript A[i,j] the same as the single subscript
A[(i-1)*ncol(A)+j].
Examples
Q = [2 4 6,8 10 12,14 16 18];
Q[8]; // same as Q[3,2]
16

The following examples all return the column vector [10, 14, 18]:
Q = [2 4 6, 8 10 12, 14 16 18];
Q[{5, 7, 9}];
Q[[5 7 9]];
ii = [5 7 9];
Q[ii];

176

Data Structures
Matrices

Chapter 7
Scripting Guide

ii = {5, 7, 9};
Q[ii];
Subscript( Q, ii );

This script returns the values 1 through 9 from the matrix P in order:
P = [1 2 3, 4 5 6, 7 8 9];
For( i = 1, i <= 3, i++,
For( j = 1, j <= 3, j++,
Show( P[i, j] )
)
);

Delete Rows and Columns
Deleting rows and columns is accomplished by assigning an empty matrix to that row or
column.
A[k, 0] = [];
A[0, k] = [];

// to delete the kth row
// to delete the kth column

Select Whole Rows or Columns
A subscript argument of zero selects all rows or columns.
P = [1 2 3, 4 5 6, 7 8 9];

Select column 2:
P[0, 2];
[2, 5, 8]

Select columns 3 and 2:
P[0, [3, 2]];
[3 2, 6 5, 9 8]

Select row 3:
P[3, 0];
[7 8 9]

Select rows 2 and 3:
P[[2, 3], 0];
[4 5 6, 7 8 9]

Select all columns and rows (the whole matrix):
P[0, 0];
[1 2 3, 4 5 6, 7 8 9]

Chapter 7
Scripting Guide

Data Structures
Matrices

177

Assignment through Subscripts
You can change values in matrices using subscripts. The subscripts can be single indices,
matrices or lists of indices, or the zero index representing all rows or columns. The number of
selected rows and columns for the insertion must either match the dimension of the inserted
argument, or the argument can be inserted repeatedly into the indexed positions.
Examples
Change the value in row 2, column 3 to 99:
P = [1 2 3, 4 5 6, 7 8 9];
P[2, 3] = 99;
Show( P );
P=[1 2 3, 4 5 99, 7 8 9]

Change the values in four locations:
P = [1 2 3, 4 5 6, 7 8 9];
P[[1 2], [2 3]] = [66 77, 88 99];
Show( P );
P=[1 66 77, 4 88 99, 7 8 9]

Change three values in one column:
P = [1 2 3, 4 5 6, 7 8 9];
P[0, 2] = [11, 22, 33];
Show( P );
P=[1 11 3, 4 22 6, 7 33 9]

Change three values in one row:
P = [1 2 3, 4 5 6, 7 8 9];
P[3, 0] = [100 102 104];
Show( P );
P=[1 2 3, 4 5 6, 100 102 104]

Change all the values in one row to the same value:
P = [1 2 3, 4 5 6, 7 8 9];
P[2, 0] = 99;
Show( P );
P=[1 2 3, 99 99 99, 7 8 9]

Operator Assignment
You can use operator assignments (such as +=) on matrices or subscripts of matrices. For
example, the following statement adds 1 to the i ‐ jth element of the matrix:
P=[1 2 3, 4 5 6, 7 8 9];
P[1,1]+=1;
Show(P);

178

Data Structures
Matrices

Chapter 7
Scripting Guide

P=[2 2 3,
4 5 6,
7 8 9];
P[1,1]+=1;
Show(P);
P=[3 2 3,
4 5 6,
7 8 9];

Ranges of Rows or Columns
If you are working with a range of subscripts, use the Index() function :: to create matrices of
ranges.
T1=1::3; // creates the vector [1 2 3]
T2=4::6; // creates the vector [4 5 6]
T3=7::9; // creates the vector [7 8 9]
T=T1|/T2|/T3; // concatenates the vectors into a single matrix
T[1::3, 2::3]; // refers to rows 1 through 3, columns 2 and 3
[2 3, 5 6, 8 9]
T[index(1,3), index(2,3)]; // equivalent Index function
[2 3, 5 6, 8 9]

Inquiry Functions
The NCol() and NRow() functions return the number of columns and rows in a matrix (or data
table), respectively:
NCol([1 2 3,4 5 6]); // returns 3 (for 3 columns)
NRow([1 2 3,4 5 6]); // returns 2 (for 2 rows)

To determine whether a value is a matrix, use the Is Matrix() function, which returns a 1 if
the argument evaluates to a matrix.
A = [20, 64,
B = {20, 64,
IsMatrix(A);
IsMatrix(B);

3];
3};
// returns 1 for yes
// returns 0 for no

Comparisons, Range Checks, and Logical Operators
JMP’s comparison, range check, and logical operators work with matrices and produce
matrices of elementwise Boolean results. You can compare conformable matrices.
AB; // greater than
A>=B; // greater or equal

Chapter 7
Scripting Guide

Data Structures
Matrices

179

A==B; // equal to
A!=B; // not equal to
A Show Tree Structure.
The parameter estimates are contained in NumberColBox(13). Continue with the script as
follows:
colBox=Report(biv) [NumberColBox(13)];
beta = colBox<|t|", probt),
NumberColBox("Lower95%", betal95),
NumberColBox("Upper95%", betau95)));

Chapter 7
Scripting Guide

Data Structures
Matrices

203

ANOVA Example
You can implement your own one‐way ANOVA. This example presents a problem involving a
three‐level factor indicating Low, Medium, and High doses and a response measurement.
Therefore, this example solves the general linear model, as follows:
Y = a + bX + e
Where:
•

Y is a vector of responses

•

a is the intercept term

•

b is a vector of coefficients

•

X is a design matrix for the factor

•

e is an error term
factor=[1,2,3,1,2,3,1,2,3];
y=[1,2,3,4,3,2,5,4,3];

First, build a design matrix for the factor:
designNom(factor);
[1 0,
0 1,
-1 -1,
1 0,
0 1,
-1 -1,
1 0,
0 1,
-1 -1]

Next, add a column of 1s to the design matrix for the intercept term. You can do this by
concatenating J and Design Nom(), as follows:
x = J(9,1,1) || designNom(factor);
[1 1 0,
1 0 1,
1 -1 -1,
1 1 0,
1 0 1,
1 -1 -1,
1 1 0,
1 0 1,
1 -1 -1]

Now, to solve the normal equation, you need to construct a matrix M with partitions:
XX Xy
yX yy
You can construct matrix M in one step by concatenating the pieces, as follows:

204

Data Structures
Matrices

Chapter 7
Scripting Guide

M=(x`*x || x`*y)
|/
(y`*x || y`*y);
[ 9 0 0 27,
0 6 3 2,
0 3 6 1,
27 2 1 93]

Now, sweep M over all the columns in X’X for the full fit model, and over the first column
only for the intercept‐only model:
FullFit=sweep(M,[1,2,3]);
InterceptOnly=sweep(M,[1]);

// full fit model
// model with intercept only

Recall that some of the standard ANOVA results are calculated by comparing the results of
these two models. This example focuses on the full fit model, which produces this swept
matrix:
[0.111111111111111 0 0 3,
0 0.222222222222222 -0.11111111111111 0.333333333333333,
0 -0.11111111111111 0.222222222222222 0,
-3 -0.33333333333333 0 11.33333333333333]

Examine the model coefficients from the upper right partition of the matrix. The lower left
partition is the same, except that the signs are reversed: 3, 0.333, 0. The results can be
interpreted as follows:
•

The coefficient for the intercept term is 3.

•

The coefficient for the first level of the factor is 0.333.

•

The coefficient for the second level is 0.

•

Because of the use of Design Nom(), the coefficient for the third level is the difference,
–0.333.

•

The lower right partition of the matrix holds the sum of squares, 11.333.

You could modify this into a generalized ANOVA script by replacing some of the explicit
values in the script with arguments. These results match those from the Fit Model platform.
See Figure 7.1.

Chapter 7
Scripting Guide

Data Structures
Matrices

205

Figure 7.1 ANOVA Report Within Fit Model

Construct the report in Figure 7.1 as follows:
1. Build a data table (described in the “Data Tables” chapter on page 275):
dt = New Table( "foo" );
dt << New Column( "y", Set Values( [1, 2, 3, 4, 3, 2, 5, 4, 3] ) );
dt << New Column( "factor", "Nominal", Values( [1, 2, 3, 1, 2, 3, 1, 2, 3] )
);

2. Run a model (described in “Launching Platforms” on page 382 in the “Scripting
Platforms” chapter):
obj = Fit Model(
Y( :y ),
Effects( :factor ),
Personality( "Standard Least Squares" ),
Run Model(
y << {Plot Actual by Predicted( 0 ), Plot Residual by Predicted( 0 ),
Plot Effect Leverage( 0 )}
)
);

3. Use JSL techniques for navigating displays (described in “Display Box Object References”
on page 408 in the “Display Trees” chapter):
ranova = obj << report;
ranova[OutlineBox(6)] << Close(0);
ranova[OutlineBox(7)] << Close(1);
ranova[OutlineBox(9)] << Close(1);
ranova[OutlineBox(5), NumberColBox( 2 )] << select;
ranova[OutlineBox(6), NumberColBox( 1 )] << select;

206

Data Structures
Associative Arrays

Chapter 7
Scripting Guide

Associative Arrays
An associative array maps unique keys to values that can be non‐unique. An associative array
is also called a dictionary, a map, a hash map, or a hash table. Keys are placed in quotes. The
value associated with a key can be a number, date, matrix, list, and so on.
Note: You can use matrices as both keys and values, or lists as both keys and values, but you
cannot mix the two. In other words, you cannot use a matrix as a key and a list as a value, or
the other way around.
Though associative arrays are not usually ordered, in JMP, keys are returned in alphanumeric
order for the purpose of iteration and serialization.
For very large lists, using an associative array instead is more efficient and faster.

Create Associative Arrays
To create an empty associative array, use the Associative Array() function or [=>].
cary = Associative Array();
cary = [=>];
[=> ]

Keys and values can be any JSL objects. Items can be added and changed with subscripting, as
follows:
cary = Associative Array();
cary["state"] = "NC";
cary["population"] = 116234;
cary["weather"] = "cloudy";
cary["population"] += 10;
cary["weather"] = "sunny";
cary["high schools"] = {"Cary", "Green Hope", "Panther Creek"};

Default Values
A default value determines the value of a key that does not exist in an associative array. If you
try to access a key that does not exist in an associative array, an error results. If you define a
default value for your associative array, accessing a key that does not exist results in the
following:
•

adds the key to the associative array

•

assigns the default value to the new key

•

returns the new key’s (default) value instead of an error

Chapter 7
Scripting Guide

Data Structures
Associative Arrays

207

If you construct an associative array from a list of strings without assigning values to the keys,
then the keys are assigned values of 1. The default value for the associative array is set to 0.
To set the default value:
cary = Associative Array();
cary << Set Default Value("Cary, NC");

To determine whether there is a default value set for an associative array, use the <value without a key.
counts = ["a"=>10, "b"=>3, =>0]; // default value of 0
counts["c"] += 1;
Show (counts);
["a" => 10, "b" => 3, "c" => 1, => 0]

In the first line, the default value is set to 0. In the second line, the key "c" does not exist in
counts. In the output, the key "c" is created with the default value of 0 and then incremented
by 1.
Associative Array Constructors
Create an empty associative array:
map = [=>];
map = Associative Array();

Create an empty associative array with a default value:
map = [=>0];
map = Associative Array(0);

Create an associative array with specific values:
map = ["yes" => 0, "no" => 1];

Create an associative array with specific values with a default value:
map = ["yes" => 0, "no" => 1, => 2];

Create an associative array from a list that contains two lists of a key‐value pair:
map = Associative Array({{"yes", 0}, {"no", 1}});

Create an associative array from a list that contains two lists of a key‐value pair with a default
value:

208

Data Structures
Associative Arrays

Chapter 7
Scripting Guide

map = Associative Array({{"yes", 0}, {"no", 1}}, 2);

Create an associative array from a list of keys and a list of values:
map = Associative Array({"yes", "no"}, {0, 1});

Create an associative array from a list of keys and a list of values with a default value:
map = Associative Array({"yes", "no"}, {0, 1}, 2);

Create an associative array from two column references. The first column contains the keys
and the second contains the values.
map = Associative Array(:name, :height);

Create an associative array from two column references with a default value:
map = Associative Array(:name, :height, .);

Create an associative array from a single list of keys or a single column reference of keys with
a default value of 0:
set = Associative Array({"yes", "no"});
set = Associative Array(:name);

Work with Associative Arrays
Find the Number of Keys
To determine the number of keys that an associative array contains, use the N Items()
function.
cary = Associative Array();
cary["state"] = "NC";
cary["population"] = 116234;
cary["weather"] = "cloudy";
cary["population"] += 10;
cary["weather"] = "sunny";
cary["high schools"] = {"Cary", "Green Hope", "Panther Creek"};
N Items(cary);
4

Add and Delete Keys and Values
To add or delete key‐value pairs from an associative array, use the following functions:
•

Insert()

•

Insert Into()

•

Remove()

•

Remove From()

Chapter 7
Scripting Guide

Data Structures
Associative Arrays

209

Note the following:
•

Insert() and Remove() return a named copy 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.
•

Remove() and Remove From() take two arguments: the associative array and a key.

•

If you insert a key with no value provided, the key is assigned a value of 1.

Examples
The following examples illustrate Insert() and Insert Into():
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"}
});

Note that aa << Insert is a message sent to an associative array that does the same thing as
the function Insert Into(). For example, these two statements are equivalent:
cary << Insert("county", "Wake");
Insert Into(cary, "county", "Wake");

The following examples illustrate Remove and Remove From:
newcary = Remove(cary, "high schools");
show(cary, newcary);

210

Data Structures
Associative Arrays

Chapter 7
Scripting Guide

cary = Associative Array({
{"county", "Wake"},
{"high schools", {"Cary", "Green Hope", "Panther Creek"}},
{"population", 116244},
{"state", "NC"},
{"weather", "sunny"}
})
newcary = ["county" => "Wake", "population" => 116244, "state" => "NC",
"weather" => "sunny"];
Remove From(cary, "weather");
show(cary);
cary = Associative Array({
{"county", "Wake"},
{"high schools", {"Cary", "Green Hope", "Panther Creek"}},
{"population", 116244},
{"state", "NC"}
});

Note that aa << Remove is a message sent to an associative array that does the same thing as
the function Remove From(). For example, these two statements are equivalent:
cary << Remove("weather");
Remove From(cary, "weather");

Find Keys or Values in an Associative Array
To determine whether a certain key is contained within an associative array, use the
Contains() function.
cary = Associative Array();
cary["state"] = "NC";
cary["population"] = 116234;
cary["weather"] = "cloudy";
cary["population"] += 10;
cary["weather"] = "sunny";
cary["high schools"] = {"Cary", "Green Hope", "Panther Creek"};
Contains(cary, “high schools”);
1
Contains(cary, “lakes”);
0

To obtain a list of all keys contained in an associative array, use the << Get Keys message.
cary <];

Applications for Associative Arrays
You can use associative arrays to quickly and efficiently perform other tasks.

212

Data Structures
Associative Arrays

Chapter 7
Scripting Guide

Get the Unique Values from a Data Table Column
A key can exist only once in an associative array, so putting a column’s values into one
automatically results in the unique values. For example, the Big Class.jmp sample data table
contains 40 rows. To see how many unique values are in the column height, run this script:
dt = Open("$SAMPLE_DATA/Big Class.jmp");
unique heights = associative array(dt:height);
nitems(unique heights);
17

There are only 17 unique values for height. You can use those unique values by getting the
keys:
unique heights << get keys;
{51, 52, 55, 56, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70}

Note: This is possible because you can use any JMP data type as keys in an associative array,
not only strings.
Using an associative array to discover unique values in a column is efficient and fast. The
following script takes some time to create a data table with 100,000 rows. Finding the 39
unique values takes very little time.
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
nms = dt:name << getvalues;
dtbig = New Table( "BigBigClass",
New Column( "name",
character,
setvalues( nms[J( 100000, 1, Random Integer( N Items( nms ) ) )] )
)
);
Wait( 0 );
t1 = Tick Seconds();
Write(
"\!N# names from BigBigClass = ",
N Items( Associative Array( dtbig:name ) ),
", elpased time=",
Tick Seconds() - t1
);

Sort a Column’s Values in Lexicographic Order
Because keys are ordered lexicographically, putting the values into an associative array also
sorts them. For example, the <...);
log=expr(print("In control at "||char( long date(today()))));
break=expr(...



Navigation menu