解析一列的字串並填入另一列你好,
我有一個包含 ProductName 的表,我想產生 OUTPUT 欄位。OUTPUT 欄位是 ProductID 與 Serial# 的串連。 如何準確解析 Serial# 並建立 OUTPUT 列?
序號範例:
- 07-08_13 表示序號# 07, 08, 13
- 09-12 表示序號# 09, 10, 11, 12
- 01-03_05-08 表示序號 01, 02, 03, 05, 06, 07, 08
- 01_04_05-08 表示序號 01, 04, 05, 06, 07, 08
- 09_11_13_14 表示序號#09,11,13,14

| 產品名稱 | 輸出 |
| AABBCC_07-08_13 | AABBCC-07 |
| AABBCC_07-08_13 | AABBCC-08 |
| AABBCC_07-08_13 | AABBCC-13 |
| AABBCC_09-12 | AABBCC-09 |
| AABBCC_09-12 | AABBCC-10 |
| AABBCC_09-12 | AABBCC-11 |
| AABBCC_09-12 | AABBCC-12 |
| EEFFGG_02 | EEFFGG-02 |
| HHIIJJ_01-07 | HHIIJJ-01 |
| HHIIJJ_01-07 | HHIIJJ-02 |
| HHIIJJ_01-07 | HHIIJJ-03 |
| HHIIJJ_01-07 | HHIIJJ-04 |
| HHIIJJ_01-07 | HHIIJJ-05 |
| HHIIJJ_01-07 | HHIIJJ-06 |
| HHIIJJ_01-07 | HHIIJJ-07 |
| KKLLLMM_01-03_05-08 | KKLLLMM-01 |
| KKLLLMM_01-03_05-08 | KKLLLMM-02 |
| KKLLLMM_01-03_05-08 | KKLLLMM-03 |
| KKLLLMM_01-03_05-08 | KKLLLMM-05 |
| KKLLLMM_01-03_05-08 | KKLLLMM-06 |
| KKLLLMM_01-03_05-08 | KKLLLMM-07 |
| KKLLLMM_01-03_05-08 | KKLLLMM-08 |
| NNOOPP_01_04_05-08 | NNOPP-01 |
| NNOOPP_01_04_05-08 | NNOOPP-04 |
| NNOOPP_01_04_05-08 | NNOOPP-05 |
| NNOOPP_01_04_05-08 | NNOOPP-06 |
| NNOOPP_01_04_05-08 | NNOOPP-07 |
| NNOOPP_01_04_05-08 | NNOPP-08 |
| QQRRSS_09_11_13_14 | QQRRSS_09 |
| QQRRSS_09_11_13_14 | QQRRSS_11 |
| QQRRSS_09_11_13_14 | QQRRSS_13 |
| QQRRSS_09_11_13_14 | QQRRSS_14 |
進階統計建模大規模客製化回覆:解析一列的字串並填入另一列是的,你可以,但是你必須弄清楚何時添加新行等的邏輯。我的建議是,您所做的就是按原樣運行程式碼,然後使用
表=>連接
將 2 個資料表放在一起。
回覆:解析一列的字串並填入另一列嗨吉姆,
可以做到沒有dt2嗎? 您可以在 dt 中新增 ProductID 和 Output 欄位嗎?
謝謝!
回覆:解析一列的字串並填入另一列由於資料是手動輸入的,因此很可能無法處理所有特殊情況,但似乎適用於當前值:
Names Default To Here(1);
//Test table
/*
dt = New Table("Untitled 4993",
Compress File When Saved(1),
New Column("ProductName",
Character,
"Nominal",
Set Values(
{"AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "EEFFGG_02",
"HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "KKLLLMM_01-03_05-08",
"KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08",
"NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08",
"QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "N4TA47_13-14-15-16-17-18", "N4TA59_13-19", "N4PX74-01-06"}
)
)
);
*/
dt = Current Data Table();
Summarize(dt, uniqProd = by(:ProductName));
newVals = Associative Array();
For Each({prodname_str}, uniqProd,
prodPart = Word(1, prodname_str, "_-");
serialPart = Substr(prodname_str, Length(prodPart) + 2);
//find and remove next range from serialPart
newVals[prodname_str] = {};
While(Length(serialPart) > 0 & serialPart != "_" & serialPart != "-",
nextRange = Regex(serialPart, "\d*-\d*");
If(IsMissing(nextRange),
break();
);
serialPart = Substitute(serialPart, nextRange, "");
If(Contains({"-", "_" }, Substr(serialPart, 1, 1)),
serialPart = Substr(serialPart, 2); //remove -_ if first character
);
nextRange = Words(nextRange, "-");
rangeVals = Index(Num(nextRange[1]), Num(nextRange[2]));
For Each({val}, rangeVals,
val = char(val);
val = Substr("00", Length(val) + 1) || val;
Insert Into(newVals[prodname_str], prodPart||"-"||val);
);
);
singleVals = Transform Each({val}, Words(serialPart, "_"),
val = char(val);
val = Substr("00", Length(val) + 1) || val;
prodPart||"-"||val;
);
Insert Into(newVals[prodname_str], singleVals);
);
vals = {{}, {}};
For Each({{key, value}}, newVals,
productname_list = Repeat({key}, N Items(value));
Insert Into(vals[1], productname_list);
Insert Into(vals[2], Sort List(value));
);
//add values to new table
dt = New Table("Productname",
New Column("ProductName", Character, "Nominal", Set Values({})),
New Column("OUTPUT", Character, "Nominal", Set Values({}))
);
dt:ProductName << Set Values(vals[1]);
dt:OUTPUT << Set Values(vals[2]);
回覆:解析一列的字串並填入另一列它只是有一個小錯誤,當我重組程式碼時,-1 沒有被刪除。

Names Default To Here( 1 );
dt = Current Data Table();
dt2 = New Table( "The Output",
New Column( "Product Name", character ),
New Column( "ProductID", Character ),
New Column( "OUTPUT", Character )
);
For( dtRow = 1, dtRow <= N Rows( dt ), dtRow++,
If( dtRow == 1 | dt:ProductName[dtRow - 1] != dt:ProductName[dtRow],
prodID = Word( 1, dt:ProductName[dtRow], "_" );
remainder = Substr( dt:ProductName[dtRow], Length( prodID ) + 2 );
While( Word( 1, remainder, "_" ) != "",
theWord = Word( 1, remainder, "_" );
If( Contains( theWord, "-" ),
numDigets = Length( Word( 1, theWord, "-" ) ) - 1;
zeros = Repeat( "0", numDigets );
For( loop = Num( Word( 1, theWord, "-" ) ),
loop <= Num( Word( 2, theWord, "-" ) ), loop++,
dt2 << Add rows( 1 );
theRow = N Rows( dt2 );
dt2:ProductName[theRow] = dt:ProductName[dtRow];
dt2:ProductID[theRow] = Word( 1, dt:ProductName[dtRow], "_-" );
dt2:output[theRow] = dt2:ProductID[theRow] || "-" ||
Substr( zeros, Length( Char( loop ) ) ) || Char( loop );
);
,
dt2 << Add Rows( 1 );
theRow = N Rows( dt2 );
dt2:output[theRow] = prodID || "-" || Word( 1, theWord, "-" );
dt2:ProductName[theRow] = dt:ProductName[dtRow];
dt2:ProductID[theRow] = Word( 1, dt:ProductName[dtRow], "_-" );
);
remainder = Substr( remainder, Length( theWord ) + 2 );
);
)
);
請確保您花時間研究程式碼,以便完全理解它是如何運作的。
回覆:解析一列的字串並填入另一列謝謝吉姆,但輸出似乎不正確。 例如前 3 行,輸出應該是:
AABBCC-07
AABBCC-08
AABBCC-13
回覆:解析一列的字串並填入另一列ProductName 資料是手動輸入的。 這些都是例外情況,並且會隨著時間的推移而改善。 請忽略他們。
回覆:解析一列的字串並填入另一列這是一個產生新表的腳本,該表根據請求擴展行。透過將資料放入新表中,它繞過了行數不足用於擴展的問題。它似乎確實可以處理所有已知的模式。

Names Default To Here( 1 );
dt = Current Data Table();
dt2 = New Table( "The Output",
New Column( "Product Name", character ),
New Column( "ProductID", Character ),
New Column( "OUTPUT", Character )
);
For( dtRow = 1, dtRow <= N Rows( dt ), dtRow++,
If( dtRow == 1 | dt:ProductName[dtRow - 1] != dt:ProductName[dtRow],
prodID = Word( 1, dt:ProductName[dtRow], "_" );
remainder = Substr( dt:ProductName[dtRow], Length( prodID ) + 2 );
While( Word( 1, remainder, "_" ) != "",
theWord = Word( 1, remainder, "_" );
If( Contains( theWord, "-" ),
numDigets = Length( Word( 1, theWord, "-" ) ) - 1;
zeros = Repeat( "0", numDigets );
For( loop = Num( Word( 1, theWord, "-" ) ) + 1,
loop <= Num( Word( 2, theWord, "-" ) ), loop++,
dt2 << Add rows( 1 );
theRow = N Rows( dt2 );
dt2:ProductName[theRow] = dt:ProductName[dtRow];
dt2:ProductID[theRow] = Word( 1, dt:ProductName[dtRow], "_-" );
dt2:output[theRow] = dt2:ProductID[theRow] || "-" ||
Substr( zeros, Length( Char( loop ) ) ) || Char( loop );
);
,
dt2 << Add Rows( 1 );
theRow = N Rows( dt2 );
dt2:output[theRow] = prodID || "-" || Word( 1, theWord, "-" );
dt2:ProductName[theRow] = dt:ProductName[dtRow];
dt2:ProductID[theRow] = Word( 1, dt:ProductName[dtRow], "_-" );
);
remainder = Substr( remainder, Length( theWord ) + 2 );
);
)
);回覆:解析一列的字串並填入另一列快速檢查有三個不同的問題:
1. 打破了 ProductNames 數量始終與序號數量相同的「規則」。 N4TA59_13-19的資料只有一次,應該是7次
2. 序號部分不以 _ 開頭 (N4PX74 - 01-06)
3. 範圍不以 _ 開頭 (N4TA47_13-14-15-16-17-18) 或這些應該只是單一值
所有這些都需要不同的修復。 這些數據品質問題是否與您的數據有關,或者腳本是否應該能夠處理所有這些問題?
回覆:解析一列的字串並填入另一列嗨,jthi,
如果我的 ProductName 是字元和數字的混合,您的腳本將無法運作。 我附上了一張桌子。 這就是我的大部分產品名稱的樣子。 謝謝你的協助。
回覆:解析一列的字串並填入另一列如果是這樣的話,應該已經可以應付了。 我做了一些小的修改(如果缺少輸出列,則創建它)。 目前,它確實依賴資料表按 ProductNames 排序的事實,這可能會在某些時候導致問題,或者您可以確保輸入表已排序(最簡單的解決方案)。
您應該能夠使用 For Each 部分,甚至可以在沒有資料表的情況下使用,只要您有名為 uniqProd 且具有 ProductNames 的清單變數。 之後只是弄清楚如何向數據表添加值。
Names Default To Here(1);
//Test table
/*
dt = New Table("Untitled 4993",
Compress File When Saved(1),
New Column("ProductName",
Character,
"Nominal",
Set Values(
{"AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "EEFFGG_02",
"HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "KKLLLMM_01-03_05-08",
"KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08",
"NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08",
"QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14"}
)
)
);
*/
dt = Current Data Table();
Summarize(dt, uniqProd = by(:ProductName));
valList = {};
For Each({prod}, uniqProd, //loop for each ProductName
prodPart = Word(1, prod, "_");
serialPart = Substr(prod, Contains(prod, "_") + 1); //remove start
possibleRanges = Words(serialPart, "_"); //if they contain -
For Each({val}, possibleRanges, //Loop for serialnumber inside the ProductName
If(Contains(val, "-"), //range
rangeVals = Words(val, "-");
For Each({val1}, Index(Num(rangeVals[1]), Num(rangeVals[2])),
valToAdd = Substr("0", Length(Char(val1))) || Char(val1);
Insert Into(valList, prodPart || "-" || valToAdd)
);
,
Insert Into(valList, prodPart || "-" || Substr("0", Length(Char(val))) || Char(val))
)
);
);
//if starting table doesn't have OUTPUT column create it
If(!Contains(dt << Get Column Names("String"), "OUTPUT"),
dt << New Column("OUTPUT", Character, "Nominal");
);
//dt[0,"OUTPUT"] = valList; subscripting, maybe a bit more difficult to understand
dt:OUTPUT << Set Values(valList);
他們的腳本嘗試執行的簡化版本:
1.腳本取得ProductName欄位中的所有唯一值
2. 腳本迴圈遍歷兩部分 For Each 迴圈中的每一個
3. 第一個迴圈遍歷唯一值並將它們分割為 Product 和 number 部分
4. 然後再次循環序號部分,將其拆分為單一值。 這些單一值與 Product 部分連接,然後將字串插入到 valList 列表中(這 4. 並不完全像我在這裡解釋的那麼簡單)。
5. 兩個循環完成後,您應該會得到一個列表,其中包含所有可能的序號。 產品部分將以字母順序排列。
6. 如果該清單存在,則將該清單新增至 OUTPUT,如果不存在,則先建立該清單。
回覆:解析一列的字串並填入另一列嗨,jthi,
是的,行數與序號數相符。
回覆:解析一列的字串並填入另一列這應該相當容易。 擷取的資料中的行數是否與序號一樣多?
回覆:解析一列的字串並填入另一列嗨,jthi,
感謝您的腳本,但我的表實際上是動態的。 每天,我都會從具有不同日期範圍的資料庫中提取此表,並且會出現不同的 ProductName 集。 所以不總是 32 行。 你的腳本幾乎可以工作,但是你能解決數組大小嗎? 謝謝。
回覆:解析一列的字串並填入另一列嗨克里斯,
我有一個腳本可以處理一些 ProductName,有時會錯誤地解析。 您能否檢查並添加程式碼來解決那些迄今為止不起作用的 ProductNames?
適用於以下範例:
EEFFGG_02
HHIIJJ_01-07
KKLLLMM_01-03_05-08
對於以下範例還不起作用:
AABBCC_07-08_13
NNOOPP_01_04_05-08
QQRRSS_09_11_13_14
dt=current data table();
(dt << New Column( "ProductID", Character )) << Set Selected;
(dt << New Column( "OUTPUT", Character )) << Set Selected;
//Parse string in ProductName column
For Each Row(
dt,
//Assign the ProductID value
:ProductID = Word( 1, :ProductName, "_-" ); //"_"
//If the ProductName changes, capture the start and end
If( :ProductName != Lag( :ProductName, 1 ),
start = Num( Word( 2, :ProductName, "_-" ) );
end = Num( Word( 3, :ProductName, "_-" ) );
);
//Assign the OUTPUT value
:OUTPUT = :ProductID || "-" || Repeat( "0", 2 - Length( Char( start ) ) ) || Char( start );
//After end value & there is an _, set start to value after _
If( start == end & Contains( :ProductName, "_"),
start = Num( Word(-2, :ProductName, "_-" ) ),
start++);
);
回覆:解析一列的字串並填入另一列好的,這可能有用。 由於使用了 For Each(對於其他版本可以用 For 替換),因此需要 JMP16。 這是一個大量腳本化的解決方案,幾乎沒有註釋,並且需要特定的起始表才能運作(需要 OUTPUT 列)。
Names Default To Here(1);
dt = New Table("Untitled 4993",
Add Rows(32),
Compress File When Saved(1),
New Column("ProductName",
Character,
"Nominal",
Set Values(
{"AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "EEFFGG_02",
"HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "KKLLLMM_01-03_05-08",
"KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08",
"NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08",
"QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14"}
)
),
New Column("OUTPUT",
Character(16),
"Nominal",
Set Values({"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""})
)
);
Summarize(dt, uniqProd = by(:ProductName));
valList = {};
For Each({prod}, uniqProd,
prodPart = Word(1, prod, "_");
serialPart = Substr(prod, Contains(prod, "_") + 1); //remove start
possibleRanges = Words(serialPart, "_"); //if they contain -
For Each({val}, possibleRanges,
If(Contains(val, "-"), //range
rangeVals = Words(val, "-");
For Each({val1}, Index(Num(rangeVals[1]), Num(rangeVals[2])),
valToAdd = Substr("0", Length(Char(val1))) || Char(val1);
Insert Into(valList, prodPart || "-" || valToAdd)
);
,
Insert Into(valList, prodPart || "-" || Substr("0", Length(Char(val))) || Char(val))
)
);
);
dt[0,"OUTPUT"] = valList;想知道使用 JMP 自己的模式匹配是否可以「輕鬆」完成這樣的事情@Craige_Hales
回覆:解析一列的字串並填入另一列謝謝,但我更喜歡 jsl 而不是互動式分隔符號。 您的方法沒有解決序號時的情況09-12。 它應該輸出如下所示的行。 不僅僅是 AABBCC-09 和 AABBCC-12。 “-”表示“至”,表示範圍。 所以 09-12 表示 09、10、11、12。
| AABBCC_09-12 | AABBCC-09 |
| AABBCC_09-12 | AABBCC-10 |
| AABBCC_09-12 | AABBCC-11 |
| AABBCC_09-12 | AABBCC-12 |
回覆:解析一列的字串並填入另一列哦,你的權利。 - 被解釋為範圍,_ 被解釋為項目的真正分隔符
回覆:解析一列的字串並填入另一列@jthi ,
你比我先一步。
你的解釋比較詳細,也是我的想法。
回覆:解析一列的字串並填入另一列你好@cchueng ,
有幾種方法。 有些是腳本基礎(尋找有人建議的回復和範例),或者您可以使用連續幾輪的文字到列(範例在此處找到)已解決:如何將一列中的文字拆分為多列? - JMP 使用者社群)然後,您可以透過選擇所需的列來連接它們,然後使用列公式或右鍵單擊所選列之一後使用「新公式列」選項。 尋找連接的字元選項。列公式更加靈活,為您提供了許多選項,請參閱有關此主題的協助(在 JMP 中建立公式)
我希望這能給你一些指引。
最好的,
回覆:解析一列的字串並填入另一列您很可能可以使用 Lag 編寫公式來執行此操作(或使用 JSL 編寫腳本),但您也可以嘗試以互動方式執行此操作,但這需要相當多的步驟:
1. 選擇「產品名稱」欄
2. 前往 Cols/Utilities/Text To 欄位並使用 - 和 _ 作為分隔符

3. 前往“表格和堆疊”,並將除第一列之外的所有其他內容新增至“堆疊列”選擇中


5. 刪除標籤列
6. 選擇剩下的兩列,然後前往行/行選擇/選擇重複行並刪除這些行

7. 選擇一個具有空值的儲存格,然後選擇「選擇符合儲存格」並刪除這些行
8. 現在選擇兩個列並右鍵單擊列標題並建立公式

9.打開剛剛建立的公式,將,更改為_

10.重新命名和刪除列/公式
11. 如果您需要ProductName 在那裡,如果你不像我一樣在第一步中不小心刪除了它,你應該能夠將它保留在那裡

如果您必須有 - 或 _ 取決於序號,您很可能可以在連接公式中處理它
編輯:我更準確地檢查了這個問題,這比我在這裡展示的要複雜一些。 您必須為某些序號新增計算,因為它們位於數字之間。 此解決方案不適用於這些情況,因為刪除重複項時某些行將被刪除。