快速顯示與正規表示式相符的行子集的資料視圖我正在尋找執行以下操作的 JSL 腳本:
-
取得活動資料表中目前選定的列。
-
選取第一個選定的列。
-
提示使用者輸入正規表示式。
-
僅選擇表中該列中的值與正規表示式相符的行。
-
開啟“資料視圖”窗口,僅顯示符合的行。
使用 JSL 可以實現這一點嗎?
自動化和腳本資料存取回覆:快速顯示與正規表示式相符的行子集的資料視圖有可能。你嘗試過什麼方法嗎?
這是一個非常基本的例子,缺少所有可以(並且很可能應該)實施的檢查
Names Default To Here(1);
dt = Current Data Table();
col = (dt << Get Selected Columns("String"))[1]; // I suggest dropping non-character columns
run_expr = Expr(
rgx_pattern = teb << Get Text; // You could check if the pattern is valid regex
dt << Select Where(!Is Missing(Regex(Column(dt, col)[Row()], rgx_pattern)));
// add check if any rows have been selected
dt << Data View; // If linked subset is fine, that is most likely better as it can avoid using select where
dt << Clear Select;
wait(0);
);
nw = New Window("",
H List Box(
Lineup Box(N Col(2),
Text Box("Enter regex pattern"),
teb = Text Edit Box("")
),
Lineup Box(N Col(1),
Button Box("OK",
run_expr
),
Button Box("Cancel")
)
)
);
Write();
回覆:快速顯示與正規表示式相符的行子集的資料視圖有用,謝謝。
說實話,我沒有包含任何程式碼,因為我的嘗試不是很接近,並且暴露了一些關於 JSL 的基本誤解,這些誤解可能來自於我從 AppleScript 和 Matlab 學習 GUI 腳本。
我本來想獲取所選列名的列表,並選擇第一個,但我期望某種返回字符串的“顯示對話框”函數,但這顯然不存在,並強制你使用這種“新窗口/列錶框/按鈕表達式”的語法,這對我來說相當不直觀,但現在我明白了它的作用,就更容易理解了。我嘗試了 ChatGPT,但它創建了一個很長的腳本,根本無法運行。
如果您有時間,請問關於您的解決方案的幾個問題:
- 為什麼「取消」按鈕沒有任何反應?我猜是因為你沒有在 Button Box() 呼叫中傳入第二個參數,但是哪個表達式可以關閉目前視窗呢? Close()?我試過“Button Box ( “取消” , 關閉 ())”,但它報了一個我無法理解的錯誤。我模仿你的方法,嘗試了“關閉視窗”,似乎可以正常工作,但我希望有更簡潔的方法。
- 您的“Get Selected Columns()”呼叫以“String”作為參數,但文件顯示函數不接受任何參數。 “String”在這裡是什麼意思?您如何知道它會被接受,或者它的作用是什麼?
- 我想在運行腳本後立即開始輸入,但焦點不在正確的位置。我嘗試在“nw=...”表達式後運行“teb << SetFocus;”,但 JMP 顯示文字編輯框無法識別該訊息。
- 是否可以讓 Regex 不區分大小寫,如果可以,怎麼做? (我嘗試添加“ 「根據文件將其新增至 Regex 參數中,但會出現錯誤。)
- 是否可以讓 return/enter 在 teb 框聚焦的情況下觸發「Ok」腳本?
- 如果使用者沒有選擇列,我想使用第一個字元列,但經過大約 20 次不同的嘗試後,我放棄了嘗試找出那是哪一列。
- 我希望資料視圖子集能夠連結起來,這會改變方法嗎?
以下是我目前所掌握的資訊:
Names Default To Here(1);
run_expr = Expr(
dt = Current Data Table();
selCols = dt << Get Selected Columns("String");
if(N Items(selCols)==0, selCols = dt << get column names("String") );
col = selCols[1];
rgx_pattern = teb << Get Text;
dt << Select Where(!Is Missing(Regex(Column(dt, col)[Row()], rgx_pattern)));
dt << Data View; // I prefer a linked subset, what changes here?
dt << Clear Select;
wait(0);
nw << Close Window;
);
close_expr = Expr(nw << Close Window);
nw = New Window("",
H List Box(
Lineup Box(N Col(2),
Text Box("Enter regex pattern"),
teb = Text Edit Box("", <
<SET width=""></SET>
<P>我喜歡打開 Big Class,運行腳本,然後輸入“ob.+t<ENTER> 「並讓它顯示只包含兩個羅伯特的資料視圖。現在它已經關閉了——運行腳本後,我必須按下 Tab 鍵,然後按 OB.+T,然後輸入兩次。</ENTER></P>
回覆:快速顯示與正規表示式相符的行子集的資料視圖- 我創建了盡可能小的範例,因此“取消”不包含關閉視窗的表達式
- 我剛剛試了一下「String」是否能像<< get column names()一樣運作,結果確實如此。測試一下不使用“String”值,看看會得到什麼(引用而不是字串)。在我看來,使用列引用簡直是一場噩夢,所以我總是使用列名的字串,並根據需要進行轉換。但是否使用引用(或任何冒號語法)完全取決於你。
- 我認為除非您希望使用複雜的解決方法,否則您將被困在標籤中,允許 SetFocus 與互動式顯示元素(TextEditBox、Button...)一起使用
- 您可以將使用者輸入轉換為 Lowercase(),並以 Lowercase() 包裝列引用。或者,我認為您可以在使用 INGORECASE 時將預設捕獲組添加到 Regex(): 正規表示式(“ABCD”, “d”, “\0”, 忽略大小寫)
- 您可以嘗試<<設定函數,它能滿足您的需求。它會在提交時執行腳本,按下回車鍵應該會觸發該操作(就像在文字編輯框外部單擊一樣)。
-
<< Get Column Names(Character, String)[1]
-
r = dt << Get Rows Where(!Is Missing(Regex(Column(dt, col)[Row()], rgx_pattern)));
dt_subset = dt << Subset(Rows(dt), Selected Columns(0), Link to original data table(1));
有很多可以改進的地方,但具體改進什麼取決於實際用例。
編輯:將原始資料表(1)的連結加入子集
回覆:快速顯示與正規表示式相符的行子集的資料視圖非常好,謝謝!
還有一個問題:如果選擇了多個列,我想對連接在一起作為字串的列值執行正規表示式;如果沒有選擇任何列,我想對*所有*列執行同樣的操作。這實際上模擬了 egrep 在表上的行為。這樣合理可行嗎?請參閱下面的註釋行,這是我的初步嘗試,但它不會只從選定的列中提取值,所以它還沒有達到這個目的(並且無法正常工作)。
Names Default To Here( 1 );
run_expr = Expr(
dt = Current Data Table();
selCols = dt << Get Selected Columns( "String" );
If( N Items( selCols ) == 0,
selCols = dt << Get Column Names( "String" )
);
col = selCols[1];
rgx_pattern = teb << Get Text;
dt << Select Where( !Is Missing( Regex( Column( dt, col )[Row()], rgx_pattern, "1", IGNORECASE ) ) );
// dt << Select Where( !Is Missing( Regex( Concat Items( dt << get Rows(Row())," "), rgx_pattern, "1", IGNORECASE ) ) );
dt << Data View;
Wait( 0 );
);
close_expr = Expr( nw << Close Window; Wait( 0 ); );
nw = New Window( "Table Egrep",
H List Box(
lb1 = Lineup Box( N Col( 2 ),
Text Box( "Select column to Enter regex pattern" ),
teb = Text Edit Box( "", Set Script( run_expr ), <
<SET width=""></SET>
<P>僅供參考,上面的“設定腳本”處理了“輸入”後立即執行的操作,效果很好。唯一缺少的就是上面的那個期望行為,以及需要按下「tab」鍵才能將焦點移到文字編輯框中。</P>
回覆:快速顯示與正規表示式相符的行子集的資料視圖它可能在某個時候開始變慢,你應該添加一個檢查,確保只選擇了字元列,但你可以建立表達式來建立連接
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
dt << Select Columns({:name, :sex});
rgx_patter = "EF";
cols = dt << Get Selected Columns("String");
conc_expr = Expr(Concat());
For Each({colname}, cols,
Insert Into(conc_expr, Name Expr(As Column(dt, colname)));
);
regex_expr = Substitute(
Expr(!Is Missing(Regex(_conc_expr_, _rgx_pattern_, "\0", IGNORECASE))),
Expr(_conc_expr_), Name Expr(conc_expr),
Expr(_rgx_pattern_), rgx_pattern
);
rows_of_interest = dt << Get Rows Where(regex_expr);
回覆:快速顯示與正規表示式相符的行子集的資料視圖您也可以使用模態視窗強制將焦點放在視窗中,但這對使用者體驗來說可能非常糟糕。
回覆:快速顯示與正規表示式相符的行子集的資料視圖就在我以為自己開始明白的時候…
文檔裡說 Expr() 「傳回未求值的參數」—說實話,這對我來說毫無意義。聽起來它只是回傳你傳入的值而已。
在你之前的程式碼中,它看起來像一個子程序,當時還挺合理的。但現在我看到的是 Expr(Concat()),我搞不清楚到底連結了什麼。之後,你用 Insert Into() 把 Expr() 物件插入進去——但 JMP 怎麼知道要把值插入哪裡呢?就連 ChatGPT 也沒能幫我理解。
這感覺就像試圖透過複製手部動作來重現魔術師的魔術一樣令人沮喪,特別是因為 Get Row() 的文檔似乎完全承諾了我想要的行為。
當然,這一切都不是你的錯,我非常感謝你的幫助。我覺得我現在的配置應該夠好了。謝謝!
回覆:快速顯示與正規表示式相符的行子集的資料視圖這裡沒有連接任何內容。 Expr(Concat()) 函數。在這種情況下,您可以將其視為參數的收集器,這些參數將在表達式建置完成後進行連接。您也可以先使用列表來建立它,然後用 concat 函數取代列表。
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
val1 = "name";
val2 = "sex";
c = {};
Insert Into(c, Name Expr(As Column(dt, val1)));
Insert Into(c, Name Expr(As Column(dt, val2)));
show(c);
Substitute Into(c, Expr(List()), Expr(Concat()));
Show(c);
// Example use
Eval(EvalExpr(
dt << New Column("Concat", Character, Nominal, Formula(
Expr(Name Expr(c))
));
));
回覆:快速顯示與正規表示式相符的行子集的資料視圖好的,我想我已經弄清楚了——這個腳本基本上是 unix/linux/mac“egrep”命令的表格等價物,即選擇/顯示僅與用戶輸入的正則表達式(搜尋字串)匹配的行:
Names Default To Here( 1 );
If(
ex = New Window( "Enter search regex",
<
<MODAL></MODAL>
<P>所有按鈕都能正常運作,即使處理數千行資料也相當快。我個人把它做成了一個插件,綁定到 cmd-shift-e(egrep)上,現在一直在使用。當然,我樂意聽取改進建議。希望這能幫到大家!</P> <BR /> <P>(非常感謝<A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/14366" target="_blank">@jthi</A>的耐心和洞察力!)</P>
回覆:快速顯示與正規表示式相符的行子集的資料視圖看起來不錯!我想做一些小改動:
- 在開啟新視窗之前,請檢查是否有開啟的表,如果沒有,則執行 stop();
- 如果沒有匹配,最後一行會拋出錯誤。您可以檢查選取的行數,如果為 0 則使用 stop() ,或向使用者顯示沒有相符的資訊。
- << 取得行數 最有可能比 << 選擇行數 更快
- << 如果您希望在第一個正規表示式沒有任何符合項目時讓使用者輸入新的正規表示式,您也可以使用 On Validate
看更多...
Names Default To Here(1);
If(N Table() == 0,
stop(); // display error message to user if necessary
);
dt = Current Data Table();
nw = New Window("Enter search regex",
<
<MODAL>
0, col = selCols[1]; , col = Column(dt, 1) << get name; ); selrows = Eval(EvalExpr( dt << Get Rows Where(!Is Missing(Regex(Expr(NameExpr(As Column(dt, col))), inputRegex, "1", IGNORECASE))); )); If(N Rows(selrows) == 0, stop(); // display error message if necessary, this could also be done already within modal window (<< On Validate), if you wish to let user perform new search ); dt2 = dt << Subset(Rows(selrows), Selected Columns(0), Link to original data table(1), Output Table("")); // dt2 << Select Rows(1::NRows(dt2)); // to select rows if necessary
</MODAL>