2017-03-07 36 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