幫助編寫一個根據用戶選擇更新的交互式窗口各位,
我正在編寫一個腳本,該腳本將部署到我組織中的用戶,以便為用戶執行一些簡單的快速統計,而無需調用分發平台。 下面的腳本是我目前擁有的截圖,然後是我遇到問題的列表。 用戶將運行 JMP 16.1,我運行 JMP Pro 16.0。 所有機器都是windows 10、64位機器。
該腳本的預期目的是顯示數字列(也許稍後我將處理分類列),並且根據選擇的單選按鈕,它將執行一些簡單的統計並在同一個窗口中顯示結果,並在同一個窗口中顯示標記為 Stats 的列計算的統計類型和所述計算結果的值。 在選擇列面板框中的適當列後,結果面板框應在選擇單選按鈕時更新。
當前的 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() 中的選項從 All 更改為 Numeric(帶或不帶“”)時,我得到一個空的列列表。 無法弄清楚為什麼會發生這種情況,當我定義了該選項時它應該只列出數字列。
- 這是我認為最難的一個:如前所述,我希望面板框“結果”中的結果在左側“統計”列中更新(其中列出了來自 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 = 命名空間(“名稱”)行作為每個函數的第一個參數。如果您創建了許多交互式 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{1} 正在訪問或評估 'tempCol' , tempCol/*###*/
也許是因為我正在運行 v13.2.1?
回复:幫助編寫一個根據用戶選擇更新的交互式窗口在你讓腳本大部分按你想要的方式工作之後,我會考慮幾個視覺方面的事情:
- 表格大小發生變化並使窗口“彈跳”一點
- 如果用戶沒有選擇列,則會出現錯誤
- 如果沒有打開數據表,您可以停止腳本執行並通知用戶
- 如果用戶更改 Col List Box 中的列,您可能應該使用當前選擇的 Radio Box 重新計算統計信息,或者將表格設置為空。
幾個想法:
- 對於結果面板框。 您可以使用 Set Widths 來防止表格更改水平大小,並使用預定義的列表大小隱藏佔位符 String Col Box 以防止垂直大小更改
- 選擇列面板框。 您可以添加 Max Selected(1) 以防止用戶選擇多個列。
- 選擇快速統計面板框。 如果用戶沒有選擇列,則進行某種“錯誤處理”。
帶有一些修改的完整腳本:
查看更多...Names Default To Here( 1 );
//Clear Symbols(); //dont like using this
If(N Items(Get Data Table List()) == 0,
Throw("No datatables open. Stopping...");
stop();
);
//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"};
maxStatCount = Max(N Items(StatsList1), N Items(StatsList2), N Items(StatsList3));
//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>
回复:幫助編寫一個根據用戶選擇更新的交互式窗口你好@jthi和@ian_jmp ,
謝謝你們倆的大力幫助! 感謝最後兩個提示@jthi ,我能夠克服關聯數組字母“問題”。 我確實喜歡 AA 的強大功能,我可以看到它們在哪裡可以派上用場,但是因為用戶的原因,我需要維護一定的秩序。
我能夠使用列表建議和您對我遇到的 Count Zero 問題的建議進行更改。 謝謝! 代碼按預期工作,現在我需要擴展它以進行分類列,然後調查我的用戶以查看他們需要的實際統計列表。
再次感謝你的幫助! 工作代碼(至少對於數字列)如下。
謝謝!,
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 正在使用 Eval 處理這個問題。
附加的腳本將給出我現在如何處理這個問題的最佳想法。
