矢量化for循环,消除数据帧中的重复数据R

时间:2017-09-01 23:19:35

标签: r vectorization

我正在使用R中的一个困难的数据操作问题。我目前正在使用for循环来解决这个问题,但是我想对它进行矢量化以使其更好地扩展。我有以下数据框可供使用:

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的重复。这是体育数据,第3-4行基本上是第1行和第2行,但是交换了team_id和opp_team_id,而其他10列(大部分)都是相同的。

这是我用于删除重复项的for循环,我认为这非常有创意,但仍然是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,反之亦然。然后它保存我想要保存在矢量中的索引。

我想对此进行矢量化 - 任何想法都会非常感激!

2 个答案:

答案 0 :(得分:4)

这与先前涉及成对重复删除的问题非常相似,如:(pair-wise duplicate removal from dataframe)。因此,按照类似的过程,并添加一点merge()来获取索引,您可以这样做:

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

答案 1 :(得分:1)

这是使用data.table的相同解决方案。我的理解是你想要删除重复副本而不只是找到唯一的索引。

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"))]