Python integration get column propertiesHi,
Is there a way to get column properties from JMP data table (such as "Design role" and "Factor changes") in python, if I use df = jmp.current() as a reference to the opened JMP data table?
I am aware of df[0].dtype and df[0].mtype to get data type and modeling type properties, but I would like to list the factors and responses in python from a DoE generated table.
Thanks!
Automation and ScriptingDesign of ExperimentsRe: Python integration get column propertiesYou can always fallback to run_jsl if some feature hasn't yet been implemented
Re: Python integration get column propertiesSure, however the following code:
df = jmp.current()
sc = jmp.run_jsl('df << Get Column Names();')
print(sc)
returns the following error: Name Unresolved: df in access or evaluation of 'df' , df/*###*/
Any ideas?
Re: Python integration get column propertiesJMP side doesn't know about your df python variables unless you "share" them. No idea what is preferred method, but you can for example use jmp.here
import jmp
dt = jmp.open(jmp.SAMPLE_DATA + 'Big Class.jmp')
jmp.here["dt"] = dt
jmp.run_jsl('''
Names Default To Here(1);
p = Column(dt, "name") << Get Property("Notes");
'''
);
print(jmp.here.get('p'))
Or you could use Python Get from JMP side of things
import jmp
dt = jmp.open(jmp.SAMPLE_DATA + 'Big Class.jmp')
jmp.run_jsl('''
dtref = Python Get(dt);
p1 = Column(dtref, "name") << Get Property("Notes");
'''
);
print(jmp.here.get('p1'))
Re: Python integration get column propertiesVery useful, thanks. Although when running:
df = jmp.current()
jmp.run_jsl('''
dt = Python Get( df );
cname = dt << Get Column Names();
''')
print(jmp.here.get('cname'))
I get "None" as output, despite obviously having some columns in my table.
Also, if using the script with "Names Default To Here(1)", my JMP crashes...
Re: Python integration get column propertiesYou get None because you don't have access to here namespace. You can use Python Send
import jmp
jmp.open(jmp.SAMPLE_DATA + 'Big Class.jmp')
df = jmp.current()
jmp.run_jsl('''
dt = Python Get(df);
cname = dt << Get Column Names("string");
Python Send(cname);
''')
print(cname) # ['name', 'age', 'sex', 'height', 'weight']
Re: Python integration get column propertiesMany thanks jthi!
This works, not only due to using Python Send (because I tried that before), but also due to specifying "string" type for cname.
Re: Python integration get column propertiesAnother question/wish: how would one scroll through all columns and check whether they have a "Design Role" or "Factor Changes" property, and list only those columns?
Re: Python integration get column propertiesDo you want the result in Python list if one of those properties is found for the columns?
Re: Python integration get column propertiesYes
Re: Python integration get column propertiesModify the logic as needed to make it easier to understand
import jmp
# demo setup
jmp.open(jmp.SAMPLE_DATA + 'Big Class.jmp')
jmp.run_jsl('''
Data Table("Big Class"):weight << Set Property("Design Role", Design Role("Continuous"));
Data Table("Big Class"):name << Set Property("Factor Changes", Easy);
''')
df = jmp.current()
jmp.run_jsl('''
dt = Python Get(df);
colnames = dt << Get Column Names("string");
res = Filter Each({colname}, colnames,
!Is Empty(Column(dt, colname) << Get Property("Design Role")) | !Is Empty(Column(dt, colname) << Get Property("Factor Changes"));
);
Python Send(res);
''')
print(res) # ['name', 'weight']
Re: Python integration get column propertiesWhile a data table is accessible from Python and JSL, df in the script above is the variable in the Python environment holding a pointer to the data table. JSL knows nothing about the variable df unless you get do a Python Get(df); from JSL, that makes a JSL variable that references the same data table that df references. While there is no Get Column Names() from the Python side, you need to think in Python instead of JSL. each column in the table has a name property see the Scripting Index.
import jmp
dt = jmp.open(jmp.SAMPLE_DATA + "Big Class.jmp")
# print then set the first column's name from python
# note the column index is zero-based just like Python.
# You can also access the column by name: print(dt['age'])
print(dt[0].name)
dt[0].name = 'First Name'
# simple list comprehension to walk data table columns
# and build a list of names from the column's name property
names = [x.name for x in dt]
print(names)
A JMP data table behaves as a list of columns and the columns behave as a list of rows. There is a wealth of information in the Python category of the scripting index. The above support has been in place since 18.0.0.
The design principle of the Python support is to behave the way a Python programmer would expect and there is rich support, especially in the jmp.DataTable object for doing things in a 'Pythonic' way.
Re: Python integration get column propertiesRegarding:
df = jmp.current()
jmp.run_jsl('''
dt = Python Get( df );
cname = dt << Get Column Names();
''')
print(jmp.here.get('cname'))
There are a couple issues with the above script. The variable cname is not in the here namespace but rather global namespace because there is not a Names Default to Here(1); in the jmp.run_jsl( ) script. So it defaults to the globals namespace. Second you do need the "Strings" parameter to the << Get Column Names("Strings") to be able pass the correct list to Python with a Python Send(cname) as been referenced by other responses. By getting cname as a list of strings also allows getting it from the Python side using the here or globals accessors in JMP 19 and beyond. Without making the list a list of strings you get a list of Opaque internal objects instead of strings.
import jmp
dt = jmp.open(jmp.SAMPLE_DATA + "Big Class.jmp")
print(dt[0].name)
dt[0].name = 'First Name'
# do it in a python way
names = [x.name for x in dt]
print(names)
# using JSL
jmp.run_jsl('''
Names default to here(1);
dt = Python Get( dt );
jname = dt << Get Column Names("String");
''')
print(jmp.here['jname'])
print(jmp.here.get('jname'))