R语言:查找重复行,无论顺序如何

4

我一整晚都在思考这个问题: 这是我的矩阵:

'a' '#' 3
'#' 'a' 3
 0  'I am' 2
'I am' 0 2

我希望把第一行和第二行看作是相同的,因为它们只是'a'和'#'的顺序不同。在我的情况下,我想删除这种类型的行。这个示例很简单,前两行是相同的,第三行和第四行也是相同的。但在我的数据集中,我不知道哪一行是“相同”的。

我正在使用R编写。谢谢。


1
你想要删除两个重复项还是只删除一个? - CCurtis
1
你想要得到什么输出?是 F T F T 还是 T T T T?(F-不重复,T-重复) - bartektartanus
我认为这很接近,但是我遇到了一个错误。奇怪的是,如果您手动指定i和n,则可以正常工作,但是当我让repeat和for控制它们时,它会出错。它应该将所有重复行标记为NA。然后你就可以把它们删除了。for(i in 1:length(df[,1])){ x=(1:length(df[,1])) x=x[!x==i] for(n in x){ if(sort(df[i,])[1]==sort(df[n,])[1]&sort(df[i,])[2]==sort(df[n,])[2]&sort(df[i,])[3]==sort(df[n,])[3]){ df[n,1:3] <- NA } } } - CCurtis
我想要的输出是:F T F T 或 T F T F,我该如何使用指示器来挑选出这些行。 - Jiang Du
3个回答

5
也许这个方案适合你。不过你想要的输出结果不是很清楚。
x <- structure(c("a", "#", "0", "I am", "#", "a", "I am", "0", "3", 
                 "3", "2", "2"), .Dim = c(4L, 3L))
x
#      [,1]   [,2]   [,3]
# [1,] "a"    "#"    "3" 
# [2,] "#"    "a"    "3" 
# [3,] "0"    "I am" "2" 
# [4,] "I am" "0"    "2" 


duplicated(
  lapply(1:nrow(x), function(y){
    A <- x[y, ]
    A[order(A)]
  }))
# [1] FALSE  TRUE FALSE  TRUE

这基本上是按行将矩阵分割,然后对每行进行排序。 duplicated 也适用于 list,因此您只需将整个内容包装在 `duplicated 中,以查找重复的项(行)。

谢谢你的帮助。但是我的测试数据有些问题:x=matrix(c(0,3,2,3,0,1,2,1,0),3,3)z=as.vector(x)ind=z>=1y=c('a','b','c')yy=expand.grid(y,y)yyy=cbind(yy,z)[ind,]duplicated( lapply(1:nrow(yyy), function(y){ A <- yyy[y, ] A[order(A)] })) [1] FALSE FALSE FALSE FALSE FALSE FALSE抱歉,我不知道如何使代码不显示在同一行。 - Jiang Du
我也遇到过这个问题!原因很可能是你在x中分配了列名。情况如下:order(A)将行进行排序,并返回带有列名的已排序行。然而,从lapply得到的结果尊重列名,并将保留列名的版本传递给duplicated。因此,duplicated所考虑的内容与x相同!请参见我的答案以获取解决方案。 - agoldev

5
对于我来说,这只产生了一个FALSE的向量,这意味着它未检测到重复项。我认为发生了这种情况:在x中分配了列名。因此,尽管order(A)将行整齐排序并返回具有已排序版本和列名的行,但从lapply得到的结果尊重列名,并将完整的列(因为名称)传递给duplicated()。因此,duplicated()所考虑的与x相同!
我受@A Handcart和Mohair的答案启发而做到了这一点,这对我有用:
duplicated(t(apply(x, 1, sort)))

这个方法也更加简短 ;)

请注意,@A Handcart And Mohair的示例仅适用于其样本数据。但如果您有命名列,则会失败。


1
作为一个开始,你可能想参考一款名为"duplicated"的出色R程序包的文档。正如该程序包所述,“duplicated()函数确定向量或数据帧中哪些元素是具有较小子脚本的元素的副本,并返回指示哪些元素(行)是重复的逻辑向量。”他们提供的一些例子包括:

示例1:

duplicated(iris)[140:143]

示例 2:
duplicated(iris3, MARGIN = c(1, 3))

例子3

anyDuplicated(iris)

示例 4

anyDuplicated(x)

例子 5

anyDuplicated(x, fromLast = TRUE)

编辑: 如果您想走一条冗长的路,可以考虑逐个字符地将每一行与数据中的每一行进行比较。为此,请想象第一行有3个字符。对于每一行,您循环遍历并检查它们是否具有此字符。如果是这样,然后您缩小并检查下一个字符。使用自创建的递归函数来处理这个问题,该函数将字符串中的值与数据框或矩阵中的所有其他行进行比较(然后仅对不匹配任何其他行的子集进行子集化),可能有效。


“duplicated”确实是正确的函数(而不是包),但我不确定这如何帮助OP得出答案。 - A5C1D2H2I1M1N2O1R2T1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接