2017-03-07 74 views
1

鉴于下面的矩阵:地划分矩阵了它的中心

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

我对所有这些矩阵,但我还没有产生的时候对应的'M1'和'M3' – Alex

+0

有什么问题你目前的方法来创建M2的答案? – A5C1D2H2I1M1N2O1R2T1

+0

我不知道这是否是最有效的方式,除此之外,最好使用类似'split'的方法创建所有这些矩阵。 – Alex

回答

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 
1

你不可能为此找到现成的函数,但你可以尝试类似下面的方法。在这里,我使用了“reshape2”包中的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 
## 
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

这是非常聪明的使用'col'。 – Alex

+0

@Alex,这也是三种方法中最有效的方法,应该可能会得到复选标记:-) – A5C1D2H2I1M1N2O1R2T1