幫助編寫根據用戶選擇更新的互動式視窗腳本各位,
我正在編寫一個腳本,該腳本將部署到我的組織中的用戶,以便為用戶執行一些簡單的快速統計,而無需調用分發平台。 下面的腳本包含我目前擁有的螢幕截圖,然後是我遇到問題的清單。 用戶將運行 JMP 16.1,我運行 JMP Pro 16.0。 所有機器都是windows 10、64位元機器。
該腳本的預期目的是顯示數字列(也許稍後我將處理分類列),並且根據選擇的單選按鈕,它將執行一些簡單的統計並在同一視窗中顯示結果,並帶有標記為「統計」的欄位用於計算的統計資料類型和所述計算結果的值。 在「選擇列」面板框中選擇適當的列後,「結果」面板框應根據選擇單選按鈕進行更新。
目前的 JMP 腳本(僅供參考,我正在熟悉的 Big Class.jmp 檔案上對其進行測試):
Names Default To Here( 1 );
//Clear Symbols();
//the width of the column list box in pixels
lbWidth = 100;
dt = Current Data Table();
//List of statistics to calculate
StatsListA = {"Mean", "Std Dev", "Max", "Min", "Range", "N"};
StatsListB = {"95% quantile", "50% quantile", "5% quantile"};
StatsListC = {};
//Expression to do math
MathA = Expr(
response_col = Column( dt, Eval( Eval Expr( Expr( ycols ) ) ) );
ymean = Col Mean( response_col );
ystdev = Col Std Dev( response_col );
ymin = Col Min( response_col );
ymax = Col Max( response_col );
yrange = ymax - ymin;
yN = Col Number( response_col );
NumResultsA = {ymean, ystdev, ymin, ymax, yrange, yN};
);
//Expresseion for other math
MathB = Expr(
);
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<RETURN result=""></RETURN>
這是我到目前為止所擁有的:

以下是我遇到問題的清單:
- 對 Radio Box() 的呼叫列出了局部變數名稱「StatsListA」等,而不是實際列出將計算的統計資料。 例如,第一個單選按鈕後面應該有以下列表:Mean、Std Dev、Max、Min、Range、N。這也應該適用於 StatsListB 和 StatsListC(我還沒有定義 C 列表)。 我不知道如何讓它評估我在 JSL 程式碼頂部建立的預定義清單。 我不想寫出每個項目,因為我可能想更改清單中的項目,並且更改局部變數 StatsListX 比每次編輯 Radio Box() 呼叫更容易。
- 現在,我不想列出所有列,而只是列出數字。 當我將 Col List Box() 中的選項從「全部」更改為「數字」(帶或不帶「」)時,我得到一個空的列列表。 無法弄清楚為什麼會發生這種情況,當我定義了該選項時它應該只列出數字列。
- 這是我認為最困難的一個:如前所述,我希望面板框中“結果”中的結果用左側“統計”列進行更新(其中列出了 StatsListX 的統計數據以及這些數據的計算結果)右欄“值”中的統計資料。 每次單擊單選按鈕時都應該更新它。 因此,如果您最初查看的是 :height,但想查看 :weight,則可以選擇 :weight,然後按一下其中一個單選按鈕以取得相關的統計摘要。 我嘗試按照此處顯示的 Set Function 範例進行操作,但沒有成功(我不太了解 Set Function 呼叫)。

MathA 的 Expr() 原本是透過關閉原始視窗並打開一個包含結果的新視窗來調用的,但在 JMP 討論中做了更多研究後,我發現可以更新現有視窗中的字段,這這是我更喜歡解決這個問題的方式。 所以,我知道我的程式碼頂部的原始編碼並不是我想要做的事情的正確程式碼。
非常感謝對此的任何幫助。
謝謝!,
DS
品質和工藝工程回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本這太整齊了。 感謝您的討論。
回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本大家好,
我要感謝您不斷提出的更改建議。 我對腳本做了一些修改,並且更喜歡最新修改的版本,所以我非常感謝其他人的貢獻。 更新後的腳本將發佈在本回應的末尾。 這個新腳本還提供字元資料類型的總計統計資料。 我還稍微修改了面板的佈局。
@jthi ,我覺得你的建議很好,我已經採納了。 我喜歡結果統計的彩色標題名稱。 另外,類似@ErraticAttack在他們的程式碼中,我這樣做了,以便在選擇新列或選擇新的數字結果時統計數據會更新。 我允許字元統計結果更改其垂直大小,因為可能有很多級別,例如 Big Class.jmp 資料表。 當更改為該列類型時,分類統計資料也會更新,但如果選擇字元列然後有人單擊數字統計選項,則會拋出錯誤。 我確實保留了寬度建議,這樣視窗就不會不斷改變寬度大小。 對不起@ErraticAttack ,目前我不太熟悉定義新的名稱空間以及如何修改程式碼。 它看起來確實非常有用,也是處理事情的好方法,我只需要學習如何正確地做到這一點。
我確信還有其他關於如何改進這一點的建議,尤其是美觀方面。 如果是這樣,請發帖,但請務必標記我,以便我知道此討論已更新。 再次感謝大家提出的改進建議。
謝謝!,
DS
下面
//GUI for quickly reporting statistics written by D. Schmidt, ver1.5
//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 = 217;
dt = Current Data Table();
//dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
//List of statistics to calculate
StatsList1 = {"µ", "σ", "Max", "Min", "Range(Δ)", "N"};
StatsList2 = {"Quantiles", "5%", "25%", "50%", "75%", "95%"};
StatsList3 = {"N", "N Missing", "N 0", "Prop 0", "Prop non-0"};
maxStatCount = Max( N Items( StatsList1 ), N Items( StatsList2 ), N Items( StatsList3 ) );
//RadioBox() arguments
rbArg = Eval List( {Concat Items( StatsList1, ", " ), Concat Items( StatsList2, ", " ), Concat Items( StatsList3, ", " )} );
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 ) );
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 )
);
statMiss = Expr(
Col N Missing( tempCol )
);
statZero = Expr(
N Items( Loc( tempCol << get as matrix, 0 ) )
);
statProp0 = Expr( statZero / statN );
statPropn0 = Expr( 1 - statProp0 );
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} );
StatListRes1 = Expr(
Eval List( {statMean, statStd, statMax, statMin, statRange, statN} )
);
StatListRes2 = Expr(
Eval List( {., statQ95, statQ75, statQ50, statQ25, statQ5} )
);
StatListRes3 = Expr(
Eval List( {statN, statMiss, statZero, statProp0, statPropn0} )
);
StatListRes = Expr(
Eval List( {StatListRes1, StatListRes2, StatListRes3} )
);
//User window
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<RETURN result=""></RETURN>
回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本你好@jimloughlin ,
我認為這只是一些調試程式碼@jthi在對我發布的原始程式碼提供他的建議編輯時使用。 我正在發布一個更新的內容,其中考慮了在此線程上撰寫的其他人的一些建議編輯。 當我發布更新的腳本時,我會標記你。 我讓它與 Big Class.jmp 數據表一起工作得很好。
謝謝!,
DS
回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本在這裡投入我的兩分錢。通常最好將腳本盡可能分成邏輯上隔離的單元或函數。為此,我發現最好從顯示樹中刪除邏輯並盡可能地扁平化函數定義。
在下面的範例解決方案中,您將看到所有函數的作用域都是自己命名空間,並且每個函數的第一行範圍是自己命名空間。在實踐中,我所做的是創建一個元編程包裝器,它會自動執行此操作,這樣我就不必明確定義自己命名空間或包含self = 命名空間(“名稱”) line 作為每個函數的第一個參數。如果您建立許多互動式 GUI,您可能想要執行類似的操作,因為它可以節省大量工作。這還有一個好處是不需要將腳本包裝在評估(評估表達式(“<代碼>”))堵塞。
另外,如果您沿著這條路線走下去,我發現最簡單的方法是為內建顯示框產生一個包裝器,該包裝器可以直接調用自己功能,並且不需要在其中放置如此多的樣板文件<< 設定函數()消息。
/* quick stats */
self = New Namespace();
self:tool name = "Quick Stats";
Eval( Eval Expr(
self:initialize = Function( {}, // called before the display tree is generated
self = Namespace( Expr( self << Get Name ) );
self:table = Current Data Table();
self:radio inputs = {
"Mean, Std Dev, Max, Min, Range, N",
"Quantiles: 0.05, 0.25, 0.50, 0.75, 0.95",
"N, N Missing, N Zero, Prop 0, Prop non-0"
};
self:stat list = {
{"Mean", "Std Dev", "Max", "Min", "Range", "N"},
{"5%", "25%", "50%", "75%", "95%"},
{"N", "N Missing", "N Zero", "Prop 0", "Prop non-0"}
};
1
);
self:content = Function( {}, // holds the display tree
self = Namespace( Expr( self << Get Name ) );
self:container = H Splitter Box(
V List Box(
H List Box(
Lineup Box( N Col( 1 ), Spacing( 0 ),
Spacer Box( <<SET auto="" stretching=""></SET>self:window << Update Window;
self:finalize();
) );
self << Get Name;
回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本當我運行 statsstart.jcl 時,出現以下錯誤:
名稱未解析:存取或評估 'tempCol' 時存在 tempCol{1},tempCol/*###*/
也許是因為我運行的是 v13.2.1?
回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本當你讓腳本基本上按照你想要的方式工作後,我會考慮一些視覺上的事情:
- 表格大小發生變化,使視窗有點“彈跳”
- 如果使用者沒有選擇列,則會出現錯誤
- 如果沒有開啟資料表,您可以停止腳本執行並通知用戶
- 如果使用者變更列列錶框中的列,您可能應該使用單選框的目前選擇重新計算統計資料或將表設為空。
幾個想法:
- 對於結果面板框。 您可以使用設定寬度來防止表格更改水平尺寸,並使用預先定義清單尺寸的隱藏佔位符字串列框來防止垂直尺寸更改
- 選擇“列”面板框。 您可以新增 Max Selected(1) 以防止使用者選擇多列。
- 選擇“快速統計”面板框。 如果使用者沒有選擇列,則進行某種「錯誤處理」。
經過一些修改的完整腳本:
看更多...
回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本你好@jthi和@ian_jmp ,
感謝你們兩位的大力幫助! 感謝最後兩個提示@jthi ,我能夠克服關聯數組字母“問題”。 我確實喜歡 AA 的力量,我知道它們可以在哪裡派上用場,但由於用戶的原因,我需要維護一定的順序。
我能夠根據清單建議和您對我遇到的計數零問題的建議進行更改。 謝謝! 該程式碼按預期工作,現在我需要擴展它以執行分類列,然後調查我的用戶以查看他們需要的實際統計資料清單。
再次感謝你的幫忙! 工作代碼(至少對於數字列)如下。
謝謝!,
DS
Names Default To Here( 1 );
Clear Symbols();
//the width of the column list box in pixels
lbWidth = 205;
dt = Current Data Table();
//dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
//List of statistics to calculate
StatsList1 = {"Mean", "Std Dev", "Max", "Min", "Range", "N"};
StatsList2 = {"Quantiles", "5%", "25%", "50%", "75%", "95%"};
StatsList3 = {"N", "N Missing", "N Zero", "Prop 0", "Prop non-0"};
//Statistics to Calculate
statMean = Expr( Col Mean( tempCol ) );
statStd = Expr( Col Std Dev( tempCol ) );
statMax = Expr( Col Max( tempCol ) );
statMin = Expr( Col Min( tempCol ) );
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 )
);
statMiss = Expr(
Col N Missing( tempCol )
);
statZero = Expr(
N Items( Loc( tempCol << get as matrix, 0 ) )
);
statProp0 = Expr( statZero / statN );
statPropn0 = Expr( 1 - statProp0 );
//RadioBox() argument
rbArg = Eval List( {Concat Items( StatsList1, ", " ), Concat Items( StatsList2, ", " ), Concat Items( StatsList3, ", " )} );
//List for results
StatList = Eval List( {StatsList1, StatsList2, StatsList3} );
StatListRes1 = Expr(
Eval List( {statMean, statStd, statMax, statMin, statRange, statN} )
);
StatListRes2 = Expr(
Eval List( {., statQ95, statQ75, statQ50, statQ25, statQ5} )
);
StatListRes3 = Expr(
Eval List( {statN, statMiss, statZero, statProp0, statPropn0} )
);
StatListRes = Expr(
Eval List( {StatListRes1, StatListRes2, StatListRes3} )
);
//User window
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<RETURN result=""></RETURN>回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本1. 由於使用關聯數組,統計資料將重新排序。 您也許可以只使用列表並修改引用以使用索引
2. 修改 0 值的計算方式可能有效。 例如,您可以將範例 Loc() 與 N Items() 一起使用:
statZero = Expr(N Items(Loc(tempCol << get as matrix, 0)));

回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本你好@jthi和@ian_jmp ,
非常感謝兩位的快速回饋! 您的建議非常有效,我能夠取得更大的進步。 現在我遇到的問題只有兩個可能非常簡單的事情,我在下麵包含了更新的程式碼。 僅供參考,我刪除了 :height 中的一些值並在 :height 中添加了一些零來測試它
問題:
- 當它列出統計數據時,它按字母順序排列,我想保持我在列表中定義的順序,這可能嗎?
- 我試圖透過先計算零的數量來計算零和非零的比例。 不幸的是,它工作得不好。 我可以將摘要放在 Expr() 中,但隨後我無法定義關聯數組,也無法獲得正確的後續計算。 我確信有一種更簡單的方法可以做到這一點,但我在 JSL 中找不到任何直接命令來只計算零。 我手動輸入了 5 個缺失值和 7 個零值。 因此,prop-non-zero 應該是 0.8,prop-zero 應該是 0.2。
Names Default To Here( 1 );
Clear Symbols();
//the width of the column list box in pixels
lbWidth = 205;
dt = Current Data Table();
//dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
//List of statistics to calculate
StatsListA = {"Mean", "Std Dev", "Max", "Min", "Range", "N"};
StatsListB = {"Quantiles", "5%", "25%", "50%", "75%", "95%"};
StatsListC = {"N", "N Missing", "N Zero", "Prop 0", "Prop non-0"};
//RadioBox() argument
rbArg = Eval List( {Concat Items( StatsListA, ", " ), Concat Items( StatsListB, ", " ), Concat Items( StatsListC, ", " )} );
//Statistics to Calculate
statMean = Expr( Col Mean( tempCol ) );
statStd = Expr( Col Std Dev( tempCol ) );
statMax = Expr( Col Max( tempCol ) );
statMin = Expr( Col Min( tempCol ) );
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 )
);
statMiss = Expr(
Col N Missing( tempCol )
);<BR /><BR />//Here's where I'm having trouble with the N Zero and proportions zero and non-zero.
Expr(
Summarize( dt, eg = By( tempCol ), em = Count( tempCol ) )
);
PropTemp1 = Expr(
Associative Array( eg, em )
);
statZero = Expr( PropTemp1["0"] );
statProp0 = Expr( statZero / statN );
statPropn0 = Expr( 1 - statProp0 );
maths = Associative Array();
maths["StatListA"] = Associative Array( StatsListA, {statMean, statStd, statMax, statMin, statRange, statN} );
maths["StatListB"] = Associative Array( StatsListB, {., statQ95, statQ75, statQ50, statQ25, statQ5} );
maths["StatListC"] = Associative Array( StatsListC, {statN, statMiss, statZero, statProp0, statPropn0} );
rbOptions = maths << Get Keys;
//User window
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<RETURN result=""></RETURN>
再次感謝您迄今為止的幫助,我希望您能在其他小事情上提供幫助。
謝謝!,
DS
回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本關於第1點,並在回覆中加入一點@jthi , 你可以做:
Names Default To Here( 1 );
//the width of the column list box in pixels
lbWidth = 100;
dt = Open("$SAMPLE_DATA/Big Class.jmp");
//List of statistics to calculate
StatsListA = {"Mean", "Std Dev", "Max", "Min", "Range", "N"};
StatsListB = {"95% quantile", "50% quantile", "5% quantile"};
//RadioBox() argument
rbArg = EvalList({ConcatItems(StatsListA, ", "), ConcatItems(StatsListB, ", ")});
//Window
New Window( "GUI for quick stats",
Panel Box( "Select Columns", ColListData = Col List Box( dt, all, <<SET data="https://community.jmp.com/" type=""></SET>
回覆:幫助編寫根據使用者選擇更新的互動式視窗腳本我做了一些快速測試並附上了腳本。 它提供了您如何解決此問題的可能想法,但可能不是最好的解決方案。
1. 使用關聯數組和表達式進行處理。
2.必須為此使用一些奇怪的語法 ColListData = Col List Box(dt, All, <
3. Set Function 正在使用 Evals 處理此問題。
隨附的腳本將給出我目前如何處理此問題的最佳想法。
