假设我有一个向量(x
),其值的顺序如下:如果它们位于nx
×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
的值在矩阵中,则NA
s将保留在相同的位置,但其他值将按从 top 左起逐行递增的顺序排列。即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
但是,我正在努力寻找一种简单的算法,该算法可以为indices
,nr
和nc
中的任意数量的NA值生成x
。有什么建议么?注意,我们可以假设不会有足够的NA
来填充整个矩阵行
答案 0 :(得分:3)
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
答案 1 :(得分:0)
如果逐行使用apply
,然后进行转置,则将获得原始矩阵排列。赋予该函数的功能是将非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顺序。