【问题标题】:Re-order vector row-wise from top of vector从向量顶部按行重新排序向量
【发布时间】:2019-03-01 19:01:09
【问题描述】:

假设我有一个向量 (x),其值的顺序是,如果它们在 nx by ny 矩阵中,则矩阵将包含从左下角开始逐行递增的值.矩阵中任何剩余的未填充值将是NA。我举个例子来说明:

nr=3
nc=3    
mx = matrix(c(7,NA,NA,4:6,1:3), nr, nc, byrow = T)
#      [,1] [,2] [,3]
# [1,]    7   NA   NA
# [2,]    4    5    6
# [3,]    1    2    3
x = c(mx)
# [1]  7  4  1 NA  5  2 NA  6  3

现在,我想将 x 重新排序为一个新向量 (y),这样如果 y 的值在矩阵中,则 NAs 将保留在同一位置,但另一个值将从 top 左侧开始按行递增。 IE。 y 应该是这样的

my = matrix(c(1,NA,NA,2:4,5:7), nr, nc, byrow = T)
#      [,1] [,2] [,3]
# [1,]    1   NA   NA
# [2,]    2    3    4
# [3,]    5    6    7
y = c(y)
# [1]  1  2  5 NA  3  6 NA  4  7

我想找到一个将 x 映射到 y 的索引向量。在这种情况下,它会是

indices = c(3, 6, 5, 4, 9, 8, 7, 2, 1)
identical(x[indices], y)
#TRUE

但是,我正在努力寻找一种简单的算法,它可以为nrnc 的任何值以及x 中的任意数量的 NA 值生成 indices。有什么建议么?注意,我们可以假设永远不会有足够的NAs 来填充整个矩阵行

【问题讨论】:

    标签: r


    【解决方案1】:
    my = t(replace(t(mx), which(!is.na(t(mx))), sort(mx)))
    my
    #     [,1] [,2] [,3]
    #[1,]    1   NA   NA
    #[2,]    2    3    4
    #[3,]    5    6    7
    match(my, mx)
    #[1] 3 6 5 4 9 8 4 2 1
    

    或者,如果索引向量必须在两个向量之间具有一一对应关系,这样它就不会两次指向同一个 NA:

    match(replace(my, is.na(my), paste0("NA", seq(sum(is.na(my))))),
          replace(mx, is.na(mx), paste0("NA", seq(sum(is.na(mx))))))
    #[1] 3 6 5 4 9 8 7 2 1
    

    【讨论】:

      【解决方案2】:

      如果你使用apply rowwise,然后转置,你会得到原来的矩阵排列。提供给 apoply 的函数用有序的非 NA 值替换非 NA 值,然后返回整行..

      t( apply(mx, 1, function(x){ x[!is.na(x)] <- x[!is.na(x)][order(x[!is.na(x)])]; x}) )
           [,1] [,2] [,3]
      [1,]    7   NA   NA
      [2,]    4    5    6
      [3,]    1    2    3
      

      如果您想要没有矩阵排列的值,只需取消分类或将其包装在 c 中。如果您想要顺序向量,那么您可以首先在函数内设置一个 y 值,即 1:length(x),然后分配 !is.na 顺序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-01
        • 1970-01-01
        • 2010-10-24
        • 1970-01-01
        • 2015-08-16
        • 1970-01-01
        • 2018-10-08
        • 2021-12-31
        相关资源
        最近更新 更多