减少' while循环'条件

时间:2016-01-25 15:37:36

标签: r control-flow

在宏观方案中,我的目标是仅打印具有相似/相同字段名称且不重复的行。那就是,如果三行重复,则只打印一次(而不是每次成对比较)。

要重现的最小数据集和库:

library(stringdist)
trye <-  data.frame(names = c('aa','aa','aa','bb','bb','cc'),
                    values = 1:6,
                    id = c('row 1', 'row 2', 'row 3', 'row 4', 'row 5', 'row 6'), 
                    stringsAsFactors = FALSE)

我的预期输出是具有相同/相似名称(1,2,3,4和5)的行:

trye 
#   names values    id
# 1    aa      1 row 1
# 2    aa      2 row 2
# 3    aa      3 row 3
# 4    bb      4 row 4
# 5    bb      5 row 5

以下两次尝试没有奏效(其他一些修改会引发错误):

#this one prints row 1,2,3,3,5,5
i <- 1
while (i < length(trye$names)) {

  dupe <- amatch(trye$names[[i]],trye$names[-i], maxDist = 1)

  if(dupe  + 1 > 0) {
    print(trye[i,])
    duperow <- dupe + 1
    print(trye[duperow,])
    trye <- trye[-c(i), ]
    i <- i + 1


  } else {
    i <- i + 1
    trye <- trye[-c(i), ]
  }

}



# this one prints rows 1,2,4,5 which is almost correct,
# it's missing row 3 (as it shares the name with row 1 and 2.
i <- 1
while (i < length(trye$names)) {

  dupe <- amatch(trye$names[[i]],trye$names[-i], maxDist = 1)

  if(dupe  + 1 > 0) {
    print(trye[i,])
    duperow <- dupe + 1
    print(trye[duperow,])
    trye <- trye[-c(i,duperow), ]
    i <- i + 1


  } else {
    i <- i + 1
    trye <- trye[-c(i,duperow), ]
  }

}

请注意,实际数据集很大,因此删除行以使比较变小似乎(或似乎)对我来说是一个好主意,实际集合中的最大距离也大于1.

1 个答案:

答案 0 :(得分:3)

你可以使用adist来自基础,获得Levenshtein距离,并过滤那些至少有一个匹配(自己除外)的人:

sapply(1:nrow(trye), function(x) sum(adist(trye[x,1], trye[,1])==0)>1)

如果您的数据非常大,因为adist价格昂贵,您可以删除所有重复项,但每个重复项除外:

trye[(!duplicated(trye$names) | rev(!duplicated(rev(trye$names)))),]

然后将它们添加回去。您可能还想检查openrefine哪种方式可以加快速度。