2017-09-01 73 views
2

我正在R中處理一個困難的數據操作問題。我目前使用for-loop來處理這個問題,但是我想對它進行向量化處理規模更好。我有以下數據框可以使用:向量化消除數據幀中重複數據的for循環R

dput(mydf) 
structure(list(team_id = c(14L, 14L, 7L, 7L, 21L, 21L, 15L, 15L 
), opp_team_id = c(7L, 7L, 14L, 14L, 15L, 15L, 21L, 21L), pg = c(3211L, 
3211L, 786L, 786L, 3914L, 644L, 1524L, 593L), sg = c(653L, 4122L, 
1512L, 1512L, 2593L, 10L, 54L, 54L), sf = c(4122L, 1742L, 2347L, 
2347L, 1352L, 3378L, 2843L, 1062L), pf = c(1742L, 886L, 79L, 
1134L, 687L, 1352L, 1376L, 1376L), c = c(3014L, 2604L, 2960L, 
2960L, 21L, 3216L, 1256L, 3017L), opp_pg = c(3982L, 3982L, 3211L, 
4005L, 1524L, 1524L, 3914L, 644L), opp_sg = c(786L, 2347L, 653L, 
653L, 54L, 802L, 2593L, 10L), opp_sf = c(1134L, 1134L, 4122L, 
1742L, 1062L, 1062L, 3105L, 3105L), opp_pf = c(183L, 183L, 1742L, 
886L, 3017L, 1376L, 3216L, 2135L), opp_c = c(2475L, 2960L, 3138L, 
3138L, 1256L, 3017L, 21L, 1957L)), .Names = c("team_id", "opp_team_id", 
"pg", "sg", "sf", "pf", "c", "opp_pg", "opp_sg", "opp_sf", "opp_pf", 
"opp_c"), row.names = c(NA, -8L), class = "data.frame") 

mydf 
    team_id opp_team_id pg sg sf pf c opp_pg opp_sg opp_sf opp_pf opp_c 
1  14   7 3211 653 4122 1742 3014 3982 786 1134 183 2475 
2  14   7 3211 4122 1742 886 2604 3982 2347 1134 183 2960 
3  7   14 786 1512 2347 79 2960 3211 653 4122 1742 3138 
4  7   14 786 1512 2347 1134 2960 4005 653 1742 886 3138 
5  21   15 3914 2593 1352 687 21 1524  54 1062 3017 1256 
6  21   15 644 10 3378 1352 3216 1524 802 1062 1376 3017 
7  15   21 1524 54 2843 1376 1256 3914 2593 3105 3216 21 
8  15   21 593 54 1062 1376 3017 644  10 3105 2135 1957 

基於我手邊的問題,行3-4和7-8在此數據框中重複。第3-4行是第1-2行的重複項,第7-8行是第5-6行的重複項。這是體育數據,除了team_id和opp_team_id切換之外,第3-4行基本上是第1和第2行,其他10列(大部分)也是如此。

這裏是我的環去除重複,我認爲這是相當有創意,但它是一個for循環儘管如此:

indices = c(1) 
TFSwitch = TRUE 
for(i in 2:nrow(mydf)) { 
    last_row = mydf$team_id[(i-1)] 
    this_row = mydf$team_id[i] 

    TFSwitch = ifelse(last_row != this_row, !TFSwitch, TFSwitch) 

    if(TFSwitch == TRUE) { 
    indices = c(indices, i) 
    } 
} 

這for循環往返檢查是否teamID列變化從行到行,如果是,則將TFSwitch從TRUE切換到FALSE,反之亦然。然後,它保存我想保留在向量中的索引。

我想向量化此 - 任何想法將不勝感激!

回答

4

這與之前涉及成對重複刪除的問題非常相似,如:(pair-wise duplicate removal from dataframe)。使用data.table

vars <- c("team_id","opp_team_id") 

mx <- do.call(pmax, mydf[vars]) 
mn <- do.call(pmin, mydf[vars]) 

merge(
    cbind(mydf[vars], ind=seq_len(nrow(mydf))), 
    mydf[!duplicated(data.frame(mx,mn)), vars] 
)[,"ind"] 

# [1] 1 2 5 6 
+0

非常感謝你 - 它實際上在我的腳本中發現了一個錯誤。當一個teamID改變了,但另一個teamID沒有,我的for循環沒有拿起這些索引。 – Canovice

1

這裏相同的解決方案:所以的類似程序,並加入少許merge()回去取了指數,你可以做。我的低調是,你想要刪除重複的對,而不僅僅是找到唯一的索引。

library(data.table) 
setDT(mydf) 
mydf[,c("id1","id2"):=list(pmax(team_id,opp_team_id),pmin(team_id,opp_team_id))] 
setkey(mydf,team_id,opp_team_id)[unique(mydf,by=c("id1","id2"))]