将矩阵的每第3行放入一个新矩阵

时间:2016-07-12 17:06:21

标签: r matrix

我想从更大的矩阵创建3个矩阵。 新矩阵应包含:

  • 新矩阵1:旧矩阵的1st, 4th, 7th....元素
  • new matrix 2:旧矩阵的2nd, 5th, 8th....元素
  • new matrix 3:旧矩阵的3rd, 6th, 9th....元素

所以如果我的矩阵看起来像这样:

    m<-matrix(c(1:3),nrow=12, ncol=2)
      [,1] [,2]
 [1,]    1    1
 [2,]    2    2
 [3,]    3    3
 [4,]    1    1
 [5,]    2    2
 [6,]    3    3
 [7,]    1    1
 [8,]    2    2
 [9,]    3    3
[10,]    1    1
[11,]    2    2
[12,]    3    3

我尝试使用像这样的for循环

for(i in 1:4){
  m1<-m[i+3,]
  m2<-m[i+4,]
  m3<-m[i+5,]
}

但这不仅不能给我第1 /第2 /第3行,而且也不能给我所有的行。

必须有一种更优雅的方式来做到这一点。

4 个答案:

答案 0 :(得分:8)

利用R:

中的索引循环规则
m[c(T, F, F),]
#      [,1] [,2]
# [1,]    1    1
# [2,]    1    1
# [3,]    1    1
# [4,]    1    1

m[c(F, T, F),]
#      [,1] [,2]
# [1,]    2    2
# [2,]    2    2
# [3,]    2    2
# [4,]    2    2

m[c(F, F, T),]
#      [,1] [,2]
# [1,]    3    3
# [2,]    3    3
# [3,]    3    3
# [4,]    3    3

当我们使用与矩阵的行数不同的向量索引矩阵时,这里具有较小长度的向量将循环,直到它们的长度匹配,例如,第一种情况,实际索引向量扩展到c(T, F, F, T, F, F, T, F, F),它将按预期获取第一行,第四行和第七行。第二种情况和第三种情况也是如此。

答案 1 :(得分:5)

我们可以使用seq来执行此操作。这对于大数据集来说会更快。

 m[seq(1, nrow(m), by =3),]

答案 2 :(得分:2)

或者我们可以这样做:

m[seq(nrow(m))%%3==1,] # 1th, 3th, 7th, ...
m[seq(nrow(m))%%3==2,] # 2th, 5th, 8th, ...
m[seq(nrow(m))%%3==0,] # 3th, 6th, 9th, ...

<强> BENCHMARKING

library(microbenchmark)

m <- matrix(c(1:3),nrow=12, ncol=2)

func_Psidom <- function(m){m[c(T, F, F),]}
func_akrun <- function(m){ m[seq(1, nrow(m), by =3),]}
func_42 <- function(m){ m[c(TRUE,FALSE,FALSE), ]}
func_m0h3n <- function(m){m[seq(nrow(m))%%3==1,]}

r <- func_Psidom(m)
all(func_akrun(m)==r)
# [1] TRUE
all(func_42(m)==r)
# [1] TRUE
all(func_m0h3n(m)==r)
# [1] TRUE

microbenchmark(func_Psidom(m), func_akrun(m), func_42(m), func_m0h3n(m))

# Unit: microseconds
           # expr    min     lq     mean  median      uq     max neval
 # func_Psidom(m)  2.566  3.850  4.49990  4.2780  4.7050  14.543   100
  # func_akrun(m) 38.923 39.779 43.58536 40.2065 41.0615 252.359   100
     # func_42(m)  2.994  3.422  4.13628  4.2770  4.7050  13.688   100
  # func_m0h3n(m) 18.820 20.103 22.37447 20.7445 21.3860 104.365   100

# ============================================================

m <- matrix(c(1:3),nrow=1200, ncol=2)
r <- func_Psidom(m)
all(func_akrun(m)==r)
# [1] TRUE
all(func_42(m)==r)
# [1] TRUE
all(func_m0h3n(m)==r)
# [1] TRUE

microbenchmark(func_Psidom(m), func_akrun(m), func_42(m), func_m0h3n(m))

# Unit: microseconds
           # expr    min      lq     mean median     uq      max neval
 # func_Psidom(m) 12.832 13.6875 14.41458 14.542 14.543   22.242   100
  # func_akrun(m) 56.033 57.3150 65.17700 57.743 58.599  289.998   100
     # func_42(m) 12.832 13.4735 14.76962 14.115 14.543   56.032   100
  # func_m0h3n(m) 76.990 78.2730 97.82522 78.702 79.557 1873.437   100

# ============================================================

m <- matrix(c(1:3),nrow=120000, ncol=2)
r <- func_Psidom(m)
all(func_akrun(m)==r)
# [1] TRUE
all(func_42(m)==r)
# [1] TRUE
all(func_m0h3n(m)==r)
# [1] TRUE

microbenchmark(func_Psidom(m), func_akrun(m), func_42(m), func_m0h3n(m))

# Unit: microseconds
           # expr      min        lq     mean   median       uq       max neval
 # func_Psidom(m)  963.665  978.6355 1168.161 1026.113 1076.798  3648.498   100
  # func_akrun(m) 1674.117 1787.6785 2808.231 1890.760 2145.043 58450.377   100
     # func_42(m)  960.672  976.2835 1244.467 1033.812 1115.507  3114.268   100
  # func_m0h3n(m) 5817.920 6127.8070 7697.345 7455.895 8055.565 62414.963   100

答案 3 :(得分:1)

当矩阵索引时,逻辑向量会被循环到行数或列数的长度:

 m[c(TRUE,FALSE,FALSE), ]

     [,1] [,2]
[1,]    1    1
[2,]    1    1
[3,]    1    1
[4,]    1    1

m[c(TRUE,FALSE,FALSE)[c(2,1,3)], ]  # the numeric vector permutes the logical values

     [,1] [,2]
[1,]    2    2
[2,]    2    2
[3,]    2    2
[4,]    2    2

m[c(TRUE,FALSE,FALSE)[c(2,3,1)], ]

     [,1] [,2]
[1,]    3    3
[2,]    3    3
[3,]    3    3
[4,]    3    3