在R中排除零值的矩阵行的顺序

4

我有一个矩阵,称为“mat”,其中包含零值。例如:

> mat
     [,1] [,2] [,3] [,4] [,5]
 [1,]    2    5    1    4    3
 [2,]    0    0    2    4    3
 [3,]    2    5    0    3    1
 [4,]    4    5    2    3    1
 [5,]    1    5    2    3    4
 [6,]    2    5    1    4    3
 [7,]    0    0    0    5    1
 [8,]    1    5    4    2    3
 [9,]    3    5    1    0    2
[10,]    2    5    4    1    3

我希望得到矩阵行索引的顺序,但需要排除零值。然而每一行中的零值应该保留在结果矩阵中,只不过放在最后。比如,对于给定的“mat”矩阵,结果应该如下所示:

> res
    [,1] [,2] [,3] [,4] [,5]
 [1,]    3    1    5    4    2
 [2,]    3    5    4    0    0
 [3,]    5    1    4    2    0
 [4,]    5    3    4    1    2
 [5,]    1    3    4    5    2
 [6,]    3    1    5    4    2
 [7,]    5    4    0    0    0
 [8,]    1    4    5    3    2
 [9,]    3    5    1    2    0
[10,]    4    1    5    3    2

我想分享以下代码:

我来写了下面这段代码:

if (sum(mat==0)>0){ # mat contains zeros
        mat[which(mat==0, arr.ind = TRUE)]=NA
        l=apply(mat, 1, function(x) order(x, na.last = NA))
        mat=t(sapply(l, '[', 1:max(sapply(l, length))))
        mat[which(is.na(mat), arr.ind = TRUE)]=0
        return(mat)
    }

你们有更好的想法或更好的算法在R中实现吗?谢谢。
测试数据:
mat <- structure(c(2, 0, 2, 4, 1, 2, 0, 1, 3, 2, 5, 0, 5, 5, 5, 5, 
0, 5, 5, 5, 1, 2, 0, 2, 2, 1, 0, 4, 1, 4, 4, 4, 3, 3, 3, 4, 5, 2, 0, 1, 
3, 3, 1, 1, 4, 3, 1, 3, 2, 3), .Dim = c(10L, 5L))

你能否将矩阵 mat 用 dput() 函数输出,以便我们进行测试? - Joris Meys
当然,这是它的翻译: 'structure(c(2, 0, 2, 4, 1, 2, 0, 1, 3, 2, 5, 0, 5, 5, 5, 5, 0, 5, 5, 5, 1, 2, 0, 2, 2, 1, 0, 4, 1, 4, 4, 4, 3, 3, 3, 4, 5, 2, 0, 1, 3, 3, 1, 1, 4, 3, 1, 3, 2, 3), .Dim = c(10L, 5L))' - 989
1个回答

3

我注意到你在res中提供的顺序包括了零。我不知道这是否符合你想要的(它与你的问题描述不符),但是如果你想要这样做,你可以这样做:

res <- apply(mat,1,function(i){
   out <- order(i)
   iszero <- i == 0
   c(out[!iszero[out]], i[iszero])
 })
 res <- t(res)

> res
      [,1] [,2] [,3] [,4] [,5]
 [1,]    3    1    5    4    2
 [2,]    3    5    4    0    0
 [3,]    5    1    4    2    0
 [4,]    5    3    4    1    2
 [5,]    1    3    4    5    2
 [6,]    3    1    5    4    2
 [7,]    5    4    0    0    0
 [8,]    1    4    5    3    2
 [9,]    3    5    1    2    0
[10,]    4    1    5    3    2

这将为您提供您提供的准确res


谢谢你的帮助,但是 res 的第二行应该是: [2,] 3 5 4 0 0 - 989
@m0h3n 看看我的修改,这不是你说的。你想要排除零的顺序。现在你有了两个。 - Joris Meys
谢谢,但您的解决方案对以下矩阵无效: mat <- structure(c(0, 3, 3, 4, 2, 3, 1, 2, 1, 1, 2, 1, 5, 3, 5, 1, 0, 4, 4, 0, 0, 2, 1, 2, 1, 4, 2, 3, 2, 3, 5, 0, 0, 0, 3, 2, 3, 5, 0, 5, 4, 5, 4, 5, 4, 5, 4, 1, 3, 2), .Dim = c(10L, 5L)) - 989
谢谢。现在我们处于同一条船上 :) 我检查了你的解决方案和我的解决方案,对于相对较大的矩阵(即50000*5),你的解决方案大约比我提出的快5倍。已经投票支持了! - 989

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