给出以下矩阵:
set.seed(1)
x <- matrix(rnorm(15),5,3)
[,1] [,2] [,3]
[1,] -0.6264538 -0.8204684 1.5117812
[2,] 0.1836433 0.4874291 0.3898432
[3,] -0.8356286 0.7383247 -0.6212406
[4,] 1.5952808 0.5757814 -2.2146999
[5,] 0.3295078 -0.3053884 1.1249309
我想提供一个行数与x
相同的行,其中整数值介于1和x
的列数之间,例如
split_vector = c(1, 2, 3, 1, 2)
并应用将矩阵x
拆分为三个矩阵的操作,每个矩阵的大小与x
相同。第一个包含split_vector
中相应索引左侧每行中的所有列,第二个包含split_vector
中索引给出的条目,第三个包含所有其他条目。例如,分别将这些矩阵表示为M1, M2, M3
,然后:
M2 <- matrix(rep(F, prod(dim(x))), ncol = ncol(x))
M2[cbind(seq_len(nrow(x)), split_vector)] <- T
M2[M2] <- x[M2] # very naughty coercion here
> M2
[,1] [,2] [,3]
[1,] -0.6264538 0.0000000 0.0000000
[2,] 0.0000000 0.4874291 0.0000000
[3,] 0.0000000 0.0000000 -0.6212406
[4,] 1.5952808 0.0000000 0.0000000
[5,] 0.0000000 -0.3053884 0.0000000
答案 0 :(得分:2)
创建输出矩阵
out1 <- out2 <- out3 <- matrix(0, nrow(x), ncol(x))
创建满足每个条件的指标,并用于添加x
中的相关值id1 <- col(x) < v
out1[id1] <- x[id1]
id2 <- col(x) == v
out2[id2] <- x[id2]
id3 <- !(id2 + id1)
out3[id3] <- x[id3]
输出
> out1
[,1] [,2] [,3]
[1,] 0.0000000 0.0000000 0
[2,] 0.1836433 0.0000000 0
[3,] -0.8356286 0.7383247 0
[4,] 0.0000000 0.0000000 0
[5,] 0.3295078 0.0000000 0
> out2
[,1] [,2] [,3]
[1,] -0.6264538 0.0000000 0.0000000
[2,] 0.0000000 0.4874291 0.0000000
[3,] 0.0000000 0.0000000 -0.6212406
[4,] 1.5952808 0.0000000 0.0000000
[5,] 0.0000000 -0.3053884 0.0000000
> out3
[,1] [,2] [,3]
[1,] 0 -0.8204684 1.5117812
[2,] 0 0.0000000 0.3898432
[3,] 0 0.0000000 0.0000000
[4,] 0 0.5757814 -2.2146999
[5,] 0 0.0000000 1.1249309
答案 1 :(得分:1)
我能够使用来自here的想法。
set.seed(1)
x <- matrix(rnorm(15),5,3)
split_vector = c(1, 2, 3, 1, 2)
x = data.frame(cbind(x,split_vector)) #cbind x and split_vector so that 'apply' can be used on rows
M1 = function(v, n){
extract = v[seq_along(v) < n]
l = length(v) - length(extract)
return(c(extract, rep(0, l)))
}
M2 = function(v, n){
extract = v[seq_along(v) == n]
l1 = n-1
l2 = length(v) - n
return(c(rep(0, l1), extract, rep(0, l2)))
}
M3 = function(v, n){
extract = v[seq_along(v) > n]
l = length(v) - length(extract)
return(c(rep(0, l), extract))
}
t(apply(x, 1, function(a) M1(v = a[-length(a)], n = a[length(a)])))
# [,1] [,2] [,3]
#[1,] 0.0000000 0.0000000 0
#[2,] 0.1836433 0.0000000 0
#[3,] -0.8356286 0.7383247 0
#[4,] 0.0000000 0.0000000 0
#[5,] 0.3295078 0.0000000 0
t(apply(x, 1, function(a) M2(v = a[-length(a)], n = a[length(a)])))
# [,1] [,2] [,3]
#[1,] -0.6264538 0.0000000 0.0000000
#[2,] 0.0000000 0.4874291 0.0000000
#[3,] 0.0000000 0.0000000 -0.6212406
#[4,] 1.5952808 0.0000000 0.0000000
#[5,] 0.0000000 -0.3053884 0.0000000
t(apply(x, 1, function(a) M3(v = a[-length(a)], n = a[length(a)])))
# [,1] [,2] [,3]
#[1,] 0 -0.8204684 1.5117812
#[2,] 0 0.0000000 0.3898432
#[3,] 0 0.0000000 0.0000000
#[4,] 0 0.5757814 -2.2146999
#[5,] 0 0.0000000 1.1249309
答案 2 :(得分:1)
您可能不会为此找到现成功能,但您可以尝试以下内容。在这里,我使用了来自&#34; reshape2&#34;的melt
。用于将list
转换为data.frame
的包(然后我将其转换为matrix
以进行矩阵索引)。
myFun <- function(inmat, splitvec) {
require(reshape2)
M1 <- M2 <- M3 <- `dim<-`(rep(0, prod(dim(inmat))), dim(inmat))
M1Val <- as.matrix(rev(melt(lapply(splitvec, function(x) (1:x)[-x]))))
M2Val <- cbind(seq_len(nrow(inmat)), splitvec)
M3Val <- as.matrix(rev(melt(lapply(splitvec, function(x) (x:ncol(inmat))[-1]))))
list(M1 = {M1[M1Val] <- inmat[M1Val]; M1},
M2 = {M2[M2Val] <- inmat[M2Val]; M2},
M3 = {M3[M3Val] <- inmat[M3Val]; M3})
}
使用样本数据,您将获得3个矩阵的列表,如下所示:
myFun(x, split_vector)
## $M1
## [,1] [,2] [,3]
## [1,] 0.0000000 0.0000000 0
## [2,] 0.1836433 0.0000000 0
## [3,] -0.8356286 0.7383247 0
## [4,] 0.0000000 0.0000000 0
## [5,] 0.3295078 0.0000000 0
##
## $M2
## [,1] [,2] [,3]
## [1,] -0.6264538 0.0000000 0.0000000
## [2,] 0.0000000 0.4874291 0.0000000
## [3,] 0.0000000 0.0000000 -0.6212406
## [4,] 1.5952808 0.0000000 0.0000000
## [5,] 0.0000000 -0.3053884 0.0000000
##
## $M3
## [,1] [,2] [,3]
## [1,] 0 -0.8204684 1.5117812
## [2,] 0 0.0000000 0.3898432
## [3,] 0 0.0000000 0.0000000
## [4,] 0 0.5757814 -2.2146999
## [5,] 0 0.0000000 1.1249309
##