您好,我需要幫助清理一些資料。表中的資料包含多個 ID、日期和類別。我對類別 1 和 2、或 1 和 2 和 3、或 1 和 3 的 ID 感興趣,同時僅保留每個類別具有最大日期的條目。您能否提供此解決方案的最佳腳本?謝謝你!
| ID | 類別 | 日期 | 成本A | 成本B | 成本C | 成本D |
| 1 | 1 | 2016 年 1 月 21 日 | 5000 | 0 | 3000 | 500 |
| 1 | 1 | 2016 年 1 月 21 日 | 1000 | 5000 | 10000 | 0 |
| 1 | 1 | 2016 年 1 月 21 日 | 20000 | 0 | 10 | 50 |
| 1 | 2 | 2016 年 1 月 22 日 | 3000 | 0 | 0 | 50000 |
| 1 | 3 | 2016年2月1日 | 1 | 10 | 900 | 0 |
| 2 | 1 | 2013 年 4 月 2 日 | 0 | 100 | 10000 | 5000 |
| 2 | 2 | 2013 年 4 月 3 日 | 0 | 0 | 0 | 642.49 |
| 2 | 1 | 2013 年 4 月 2 日 | 1 | 10 | 900 | 0 |
| 3 | 2 | 2015 年 3 月 6 日 | 50 | 0 | 0 | 259.58 |
這是一個應該可以工作的小腳本。它找到符合您定義的行。然後將這些行子集到一個新表中。
Names Default To Here( 1 );
dt = Current Data Table();
For Each Row(
If( :date == Col Maximum( :date, :ID ),
currID = :ID;
//currID="1"
cats = Associative Array( dt:category[dt << get rows where( :ID == currID )] ) << get keys;
If( cats[1] == "1" & Length( cats ) > 1,
dt << select rows( Row() )
);
)
);
dtNew = dt << subset( selected columns(0), selected rows(1),
output table("Final")
);
// The above code will allow multiple rows within a given ID, when there are
// multiple rows with the same maximum date. Run the below code to
// get rid of the multiple entries, if that is what is desired
dtNew << select duplicate rows(Match(:ID));
dtNew << delete rows;


如果執行上述腳本的最後 2 行,則會刪除重複的 ID 行。

吉姆,
感謝您的協助。對於任何混亂,我深表歉意。我需要決賽表中必須具有類別 1 和 2 和/或 3 的每個 ID。如果同一類別有重複的 ID,我需要具有最大日期的行。應在此處提供該表。提前謝謝你的幫忙。
| ID | 類別 | 日期 | 成本A | 成本B | 成本C | 成本D |
| 1 | 1 | 2016 年 1 月 21 日 | 20000 | 0 | 10 | 50 |
| 1 | 2 | 2016 年 1 月 22 日 | 3000 | 0 | 0 | 50000 |
| 2 | 1 | 2013 年 4 月 2 日 | 0 | 100 | 10000 | 5000 |
| 2 | 2 | 2013 年 4 月 3 日 | 0 | 0 | 0 | 642.49 |
| 3 | 1 | 2015 年 3 月 6 日 | 3000 | 0 | 0 | 第817章 |
| 3 | 2 | 2015 年 3 月 6 日 | 50 | 0 | 0 | 259.58 |
| 4 | 1 | 2015 年 3 月 6 日 | 10000 | 0 | 0 | 710.16 |
| 4 | 2 | 2015 年 3 月 6 日 | 5000 | 0 | 0 | 1087 |
| 4 | 3 | 2015 年 3 月 16 日 | 0 | 0 | 0 | 326.7 |
我上面的範例將類別作為字元列。你的例子是數字。我還更改了邏輯以確保至少有類別 1&2、1&3 或 1&2&3
Names Default To Here( 1 );
dt = Current Data Table();
For Each Row(
If( :date == Col Maximum( :date, :ID ),
currID = :ID;
cats = Associative Array( dt:category[dt << get rows where( :ID == currID )] ) << get keys;
show(cats);
If( Length( cats ) > 1,
If( cats[1] == 1 & (cats[2] == 2 | cats[2] == 3),
dt << select rows( Row() )
)
);
)
);
dtNew = dt << subset( selected columns( 0 ), selected rows( 1 ), output table( "Final" ) );
這是使用 Col 函數解決此問題的一種方法
Names Default To Here(1);
dt = New Table("Untitled 3",
Add Rows(11),
Compress File When Saved(1),
New Column("ID", Numeric, "Continuous", Format("Best", 12), Set Values([1, 1, 1, 2, 3, 3, 4, 4, 4, 4, 4])),
New Column("Category", Character, "Nominal", Set Values({"A", "A", "B", "A", "A", "C", "A", "A", "B", "B", "C"})),
New Column("Date", Numeric, "Continuous", Format("Best", 12), Set Values([1, 1, 2, 1, 1, 2, 1, 2, 1, 2, 1]))
);
dt << New Column("KEEP", Numeric, Nominal, Formula(
Col Sum(Row() == Col Min(Row(), :category, :id), :id) > 1 & :date == Col Max(:date, :category, :id)
));
將公式變更為 << 選擇位置 / << 取得行位置或將其與子集一起使用以取得要保留的行。

編輯:
原始版本沒有考慮類別 1 可能會遺失(這假設類別是數字列)
New Column("KEEP", Numeric, Nominal, Formula(
Col Sum(Row() == Col Min(Row(), :category, :id), :id) > 1
& :date == Col Max(:date, :category, :id)
& Col Sum(If(:category == 1, 1, .), :id)
));