我有一個具有E型SKU或非E型SKU的數據集。我的目標是找出我是否以任何順序銷售E型SKU以及類似的非E型SKU。按組查找特定項目的行復制
例如,如果我用W123出售E123,這將被視爲重複。如果我將E123與另一個E123一起銷售,這不會被視爲重複。如果我用W123出售W123,它也不會被視爲重複。總而言之,我需要找到至少有一個E型SKU和至少一個非E型SKU的副本。
我在SO上詢問的上一個示例與此類似(Find row-wise duplicates by groups),但該方法的挑戰在於,當應用sub("^E","", Product)
時,我不再知道我是在比較E型SKU與E型SKU還是E非E型SKU的SKU型SKU。
這裏的樣本數據:
dput(Test_File)
structure(list(Order = c(1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5,
5, 5), Product = c("E12960", "E12960", "E12960", "W12960", "W12960",
"W12960", "E1234", "E2345", "W2355", "A1235", "C-A-1234", "W-1234",
"A-1234", "C-1234")), .Names = c("Order", "Product"), row.names = c(NA,
14L), class = "data.frame")
這裏的預期輸出:
dput(Output_File)
structure(list(Order = c(1, 2, 3, 4, 5), Duplicate = c("N", "Y",
"N", "N", "N")), .Names = c("Order", "Duplicate"), row.names = c(NA,
5L), class = "data.frame")
這是我的工作代碼:
Test_File[,"ESKU_Present"]<-grepl("^E",Test_File$Product,ignore.case = TRUE)
#Strip initial identifiers
toMatch<-c("^E","^W","^A","^C-","^W-","C-A-","^A-")
Test_File[grepl(paste(toMatch,collapse="|"),Test_File$Product,ignore.case = TRUE),"New_Product_ID"]<-sub(paste(toMatch,collapse="|"), "", Test_File$Product)
Output <- Test_File %>%
dplyr::group_by(Order) %>%
#find those orders that have at least one ESKU and one non-ESKU
mutate(Duplicate = (any(ESKU_Present ==c("FALSE")) & any(ESKU_Present == c("TRUE")))) %>%
dplyr::filter(Duplicate == "TRUE") %>%
dplyr::summarise(Final_Flag = any(duplicated(New_Product_ID))) %>%
right_join(Test_File) %>%
dplyr::select(Order, Final_Flag)
Output[is.na(Output$Final_Flag),"Final_Flag"]<-FALSE
Output<-dplyr::distinct(Output)
我有兩個問題:
a)如何我是否使用data.table
做我想做的事情? b)有沒有更快的方法來做到這一點?我問這是因爲在我的原始數據集上,它有大約1M行,上面的代碼是永久的。
謝謝。你是一個天才 - 你做了兩行只有10行的東西。你介意解釋你做了什麼?我不太熟悉'data.table',我仍然在學習...... – watchtower
謝謝。你知道在sub()中寫表達式的好資源嗎?我總是爲此而掙扎。我剛剛瞭解了'\\ d +'和'\\ D +'... – watchtower
@watchtower我添加了一些說明。讓我知道如果你需要進一步的解釋 – akrun