R独特的列或行与NA不可比

任何人都知道unique()或duplicated()的不兼容参数是否已经超出了不可比的= FALSE?

也许我不明白它应该如何工作……

无论如何,我正在寻找一个灵活的解决方案,只保留除了额外的NA之外与另一列相同的唯一列(或行)?我可以使用cor()来强制它,例如,对于成千上万的列,这是难以处理的.

这是一个例子,抱歉,如果它有点凌乱,但我认为这说明了重点.制作一些矩阵z:

z <- matrix(sample(c(1:3, NA), 100, replace=TRUE), 10, 10)
colnames(z) <- paste("c", 1:10, sep="")
rownames(z) <- paste("r",1:10, sep="")

让我们添加一些带有额外NA的重复列,并随机化列,(这样它们并不总是在最后).

c3.1 <- z[, 3]
c3.1[sample(1:10, 3)] <- NA
c8.1 <- z[, 8]
c8.1[sample(1:10, 5)] <- NA

z <- cbind(z, c3.1, c8.1)
z <- z[, sample(1:ncol(z))]

所以我可以按缺失的数字排序,然后看起来似乎duplicated()或unique()可以工作,但它不喜欢忽略丢失.

missing <- apply(z, 2, function(x) {length(which(is.na(x)))})
z.sorted <- z[, order(missing)]

z.sorted[,!duplicated(z.sorted,MARGIN=2)]
unique(z.sorted,MARGIN=2)

我认为这是不兼容的论点专门针对的内容,但它似乎尚未实现:

z.sorted[,!duplicated(z.sorted,MARGIN=2,incomparables=NA)]
unique(z.sorted,MARGIN=2,incomparables=NA)

我知道我很快就会找到一个不太优雅的解决方案,我想我更想问为什么还没有实现呢?或者如果我只是错误地使用它.似乎我经常碰到这个,但我搜索了很长一段时间而没有找到答案.有什么想法吗?

最佳答案 正如您所怀疑的那样,对于data.frame和矩阵方法的唯一,不可比的!= FALSE尚未实现.它以默认方法实现,该方法用于没有dims的向量.例如.:

unique(c(1, 2, 2, 3, 3, 3, NA, NA, NA), incomparables=2)
## [1]  1  2  2  3 NA

unique(c(1, 2, 2, 3, 3, 3, NA, NA, NA), incomparables=NA)
## [1]  1  2  3 NA NA NA

看一下unique.matrix与unique.default的来源(只需在控制台中键入函数名称并按Enter键,或在RStudio中按F2键在新窗格中打开源代码).

在您的情况下,您可以使用outer来创建一个矩阵,指示特定的行/列对是否相同,而忽略了NA.

same <- outer(seq_len(ncol(z)), seq_len(ncol(z)), 
              Vectorize(function(x, y) all(z[, x]==z[, y], na.rm=TRUE)))

same

##        [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10] [,11] [,12]
##  [1,]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [2,] FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
##  [3,] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
##  [4,] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [5,] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
##  [6,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
##  [7,] FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
##  [8,] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
##  [9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [10,] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
## [11,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
## [12,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

然后,如果你只想保留那些与第二列相同的列(对我来说是c8.1列 – 请参阅本文的底部我所使用的完整z矩阵),你可以这样做:

z[, same[2, ]] # or, equivalently, z[, same[, 2]]

##     c8.1 c8
## r1     2  2
## r2     1  1
## r3    NA  3
## r4    NA  1
## r5     3  3
## r6    NA  1
## r7     2  2
## r8    NA  1
## r9     3  3
## r10   NA  1

要将矩阵缩减为唯一的列集(忽略NA),并且具有最少数量的NA,您可以执行以下操作:

z[, unique(sapply(apply(same, 2, which), function(x) 
  x[which.min(colSums(is.na(z))[x])]))]

##      c7 c8 c3 c1 c6 c10 c2 c9 c4
##  r1   2  2  1  2  1   1  1  2 NA
##  r2   3  1  3  1  3  NA  1  2  2
##  r3   2  3  2  3  1  NA  2  1 NA
##  r4   2  1  1  2  2   1  3 NA  2
##  r5  NA  3  2  1  3   2 NA NA  3
##  r6   2  1  2  2  1   1  2  1 NA
##  r7   2  2  2  2 NA   3  1  2  2
##  r8  NA  1  1  3  2  NA  1 NA  1
##  r9   1  3  3  2 NA   2  1 NA  2
## r10  NA  1  1 NA  1   1  1  2  3

供参考,这是我正在使用的z:

    c7 c8.1 c3 c1 c5 c10 c8 c6 c2 c3.1 c9 c4
r1   2    2  1  2  1   1  2  1  1    1  2 NA
r2   3    1  3  1  3  NA  1  3  1    3  2  2
r3   2   NA  2  3  1  NA  3  1  2    2  1 NA
r4   2   NA  1  2 NA   1  1  2  3   NA NA  2
r5  NA    3  2  1  3   2  3  3 NA    2 NA  3
r6   2   NA  2  2  1   1  1  1  2    2  1 NA
r7   2    2  2  2  1   3  2 NA  1    2  2  2
r8  NA   NA  1  3 NA  NA  1  2  1   NA NA  1
r9   1    3  3  2  1   2  3 NA  1   NA NA  2
r10 NA   NA  1 NA NA   1  1  1  1    1  2  3
点赞