Dear All,
I'm updating a script that I wrote some time ago. You can find the original script/idea here. The original script was meant to update some basic statistical information as a user clicks through the columns listed in the "Select Columns" Panel Box of the current data table.
What I'd like to do now is add some panel boxes that also update when the user clicks on the different columns available from the current data table. I want to update a panel box that shows the distribution of the data within the column -- actually showing the results of the distribution platform (if possible), and not just generating a Graph Builder or Graph Box to do it. The other is a panel box that shows the results of the Explore Outliers platform. I'd like both of these panel boxes to update when the user selects a new column to review.
Using the "Big Class.jmp" example data file, I've made a little mock-up of what I'd like it to show. I've included the JSL at the very end.
This is the current view of the user interface.
![SDF1_0-1691430068715.png SDF1_0-1691430068715.png](https://community.jmp.com/t5/image/serverpage/image-id/55613iDC7CD93903FD47BB/image-size/medium?v=v2&px=400)
This is the concept of how I'd like it to look like when someone clicks on the column of interest, in this case :height.
![SDF1_3-1691432089953.png SDF1_3-1691432089953.png](https://community.jmp.com/t5/image/serverpage/image-id/55616i4188FBFBF23F12BB/image-size/medium?v=v2&px=400)
Then, when the user clicks on a new column, say :weight, the display updates and shows this:
![SDF1_4-1691432174135.png SDF1_4-1691432174135.png](https://community.jmp.com/t5/image/serverpage/image-id/55617i3238EDB6370CBD0D/image-size/medium?v=v2&px=400)
I don't actually need the summary statistics in the distribution platform, but I want the distribution with the box plot and data points graphed above it, with the additional information in the box plot, like the mean, median, and maximum 50% of the data -- you can't add these easily in graph builder, for example.
You don't have to solve this entirely for me, but if anyone has suggestions on how to get started, I'd really appreciate it, because the ideas I've tried so far aren't working. I don't even know if this is possible, but I'm hoping it is. I'd prefer no to have to do it as a dashboard.
Thanks in advance for your help! Below is the JSL
Thanks!,
DS
//GUI for quickly reporting statistics written by D. Schmidt, ver2.0
//Thanks to JMP User community members: jthi, ian_jmp, and ErraticAttach for helpful suggested changes.
Names Default To Here( 1 );
Clear Symbols();
//the width of the column list box in pixels
lbWidth = 200;
dt = Current Data Table();
//dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
//List of statistics to calculate
StatsList1 = {"µ", "σ", "Max", "Min", "Range(Δ)", "N"};
StatsList2 = {"µ", "Median", "Mode", "N"};
StatsList3 = {"Quantiles", "5%", "25%", "50%", "75%", "95%", "Int. Q. Range"};
StatsList4 = {"N", "N Missing", "N 0", "Prop 0", "Prop non-0"};
maxStatCount = Max( N Items( StatsList1 ), N Items( StatsList2 ), N Items( StatsList3 ), N Items( StatsList4 ) );
//RadioBox() arguments
rbArg = Eval List(
{Concat Items( StatsList1, ", " ), Concat Items( StatsList2, ", " ), Concat Items( StatsList3, ", " ), Concat Items( StatsList4, ", " )}
);
rbcArg = {"Select for categorical columns"};
//Statistics to Calculate
statMean = Expr( Col Mean( tempCol ) );
statStd = Expr( Col Std Dev( tempCol ) );
statMax = Expr( Col Max( tempCol ) );
statMin = Expr( Col Min( tempCol ) );
statMed = Expr( Col Median( tempCol ) );
statMode = Expr(
Mode( dt:tempcol << getvalues )
);
statRange = Expr(
Col Max( tempCol ) - Col Min( tempCol )
);
statN = Expr( Col Number( tempCol ) );
statQ95 = Expr(
Col Quantile( tempCol, 0.05 )
);
statQ75 = Expr(
Col Quantile( tempCol, 0.25 )
);
statQ50 = Expr(
Col Quantile( tempCol, 0.5 )
);
statQ25 = Expr(
Col Quantile( tempCol, 0.75 )
);
statQ5 = Expr(
Col Quantile( tempCol, 0.95 )
);
statIntQR = Expr( StatQ25 - StatQ75 );
statMiss = Expr(
Col N Missing( tempCol )
);
statZero = Expr(
N Items( Loc( tempCol << get as matrix, 0 ) )
);
statProp0 = Expr( statZero / statN );
statPropn0 = Expr( 1 - statProp0 );
OrdStats = Expr(
colmodeltype = tempCol << Get Modeling type;
If( colmodeltype == "Ordinal",
orddist = dt << Distribution( Nominal Distribution( Column( tempCol ) ), Invisible );
rpt_orddist = orddist << Report;
ordlvl = rpt_orddist[String Col Box( 1 )] << Get;
ordCount = rpt_orddist[Number Col Box( 1 )] << Get;
ordProb = rpt_orddist[Number Col Box( 2 )] << Get;
OrdSummNMiss = rpt_orddist[List Box( 7 )][2] << Get Text;
OrdSummLvl = rpt_orddist[List Box( 8 )][1] << Get text;
OrdnumNMiss = Num( OrdSummNMiss );
OrdnumLvl = Num( OrdSummLvl );
Orddist << Close Window;
);
Insert Into( Ordlvl, {"N Missing", "N Levels"} );
Insert Into( OrdCount, OrdnumNMiss );
Insert Into( OrdCount, OrdnumLvl );
);
CatStats = Expr(
coltype = tempCol << Get Data type;
If( coltype == "Character",
catdist = dt << Distribution( Nominal Distribution( Column( tempCol ) ), Invisible );
rpt_catdist = catdist << Report;
lvl = rpt_catdist[String Col Box( 1 )] << Get;
Count = rpt_catdist[Number Col Box( 1 )] << Get;
Prob = rpt_catdist[Number Col Box( 2 )] << Get;
SummNMiss = rpt_catdist[List Box( 7 )][2] << Get Text;
SummLvl = rpt_catdist[List Box( 8 )][1] << Get text;
numNMiss = Num( SummNMiss );
numLvl = Num( SummLvl );
catdist << Close Window;
);
Insert Into( lvl, {"N Missing", "N Levels"} );
Insert Into( Count, numNMiss );
Insert Into( Count, numLvl );
);
//List for results
StatList = Eval List( {StatsList1, StatsList2, StatsList3, StatsList4} );
StatListRes1 = Expr(
Eval List( {statMean, statStd, statMax, statMin, statRange, statN} )
);
StatListRes2 = Expr(
Eval List( {statMean, statMed, statMode, statN} )
);
StatListRes3 = Expr(
Eval List( {., statQ95, statQ75, statQ50, statQ25, statQ5, StatIntQR} )
);
StatListRes4 = Expr(
Eval List( {statN, statMiss, statZero, statProp0, statPropn0} )
);
StatListRes = Expr(
Eval List( {StatListRes1, StatListRes2, StatListRes3, StatListRes4} )
);
//Expression to handle the distribution platform
DistExpr = Expr(
Distribution(
Continuous Distribution(
Column( tempCol ),
Quantiles( 0 ),
Horizontal Layout( 1 ),
Vertical( 0 ),
Customize Summary Statistics( N Zero( 1 ) )
),
SendToReport( Dispatch( tempCol, "Summary Statistics", OutlineBox, {Close( 1 )} ) )
)
);
//Expression for Outliers
OutlierExpr = Expr(
Explore Outliers( Y( tempCol ), Quantile Range Outliers)
);
//User window
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<Return Result,
<<On Validate,
Border Box( Left( 3 ), Top( 2 ),
V List Box(
Text Box( "Quick Stats Window", <<Set Font Size( 12 ) ),
H List Box(
Panel Box( "Select Columns",
ColListData = Col List Box(
dt,
All,
Grouped,
Max Selected( 1 ),
width( lbWidth ),
nLines( 10 ),
<<On change(
lvlcb << Set( {} );
ccb << Set( {} );
pcb << Set( {} );
scb << Set( {} );
ncb << Set( {} );
tempCol = Column( dt, (ColListData << Get Selected) );
If( !Contains( dt << Get Column Names, tempCol ),
Throw( "No Column Selected" ),
coltype = tempCol << Get Data type;
colmodeltype = tempCol << Get Modeling type;
If(
Coltype == "Numeric" & Colmodeltype == "Continuous",
vals = qstats << get;
scb << Set( StatList[vals] );
ncb << Set( StatListRes( vals )[vals] );,
Colmodeltype == "Ordinal" & Coltype == "Numeric",
OrdStats;
vals = qstats << get;
scb << Set( StatList[vals] );
ncb << Set( StatListRes( vals )[vals] );
lvlcb << Set( Ordlvl );
ccb << Set( OrdCount );
pcb << Set( Ordprob );,
Coltype == "Character",
CatStats;
lvlcb << Set( lvl );
ccb << Set( Count );
pcb << Set( prob );
);
);
)
)
),
Panel Box( "Numerical Results",
ntb = Table Box(
scb = String Col Box( "Stats", {}, <<set width( 75 ) ),
ncb = Number Col Box( "Values", {} ),
String Col Box( "", Repeat( {""}, maxStatCount ), Visibility( "Hidden" ) ) //you can use hidden string col box to "force" height to Table box
)
),
Panel Box( "Categorical Results",
ctb = Table Box(
lvlcb = String Col Box( "Level", {}, <<set width( 70 ) ),
ccb = Number Col Box( "Count", {} ),
pcb = Number Col Box( "Prob", {} ),
String Col Box( "", Repeat( {""}, maxStatCount ), Visibility( "Hidden" ) ) //you can use hidden string col box to "force" height to Table box
)
),
Panel Box( "Action",
Lineup Box( N Col( 1 ),
Button Box( "Cancel/End", nwin << Close Window ),
Text Box( " " ),
Button Box( "Help", Web( "https://www.jmp.com/en_ch/support/online-help-search.html?q=*%3A*" ) )
)
)
),
V List Box(
H List Box(
Panel Box( "Choose numerical quick stats",
qstats = Radio Box(
rbArg,
<<Set Function(
Function( {this, index},
{},
lvlcb << Set( {} );
ccb << Set( {} );
pcb << Set( {} );
scb << Set( {} );
ncb << Set( {} );
vals = this << get;
If(
!Contains( dt << Get Column Names, tempCol ), Throw( "No Column Selected" ),
Coltype != "Numeric", Throw( "Wrong Column Type for Numerical Stats" ),
tempCol = Column( dt, (ColListData << Get Selected) );
colmodeltype = tempCol << Get Modeling type;
coltype = tempCol << Get Data type;
If( coltype == "Numeric" & colmodeltype == "Continuous",
scb << Set( StatList[vals] );
ncb << Set( StatListRes( vals )[vals] );
);
If( Colmodeltype == "Ordinal" & Coltype == "Numeric",
OrdStats;
scb << Set( StatList[vals] );
ncb << Set( StatListRes( vals )[vals] );
lvlcb << Set( Ordlvl );
ccb << Set( OrdCount );
pcb << Set( Ordprob );
);
);
)
)
),
),
Panel Box( "Distribution", DistExpr)
),
Panel Box( "Explore Outliers", OutlierExpr)
)
),
),
),
);
//qstats << Set Width( 200 ) << Set Wrap( 200 );
ValueDlg;