在矩阵中的两个任意列之间插入一列

时间:2014-04-24 17:28:33

标签: r

我想在现有矩阵中插入一列。我写了以下函数:

> insert.col <- function(A,x,p)
    {

     cbind(x,A) -> B
     if(p == 1) return(B)

     for(i in 1:(p-1)){
     if(i == 1) B <- B[,c(i+1,i,(i+2):ncol(B))]
     else B <- B[,c(1:(i-1),i+1,i,(i+2):ncol(B))]
     }
    return(B)
    }

A ---矩阵

x ---具有兼容尺寸的矢量

p ---你希望x出现哪一列

示例:

A <- matrix(1:10,nrow=2)

> A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    3    5    7    9
[2,]    2    4    6    8   10

> insert.col(A,c(0,0),2)
       x
[1,] 1 0 3 5 7  9
[2,] 2 0 4 6 8 10

> insert.col(A,c(0,0),5)
             x
[1,] 1 3 5 7 0  9
[2,] 2 4 6 8 0 10

> str(insert.col(A,c(0,0),2))
 num [1:2, 1:6] 1 2 0 0 3 4 5 6 7 8 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:6] "" "x" "" "" ...

我想不出为什么R指定dimnames?有没有优雅的方式实现这个?

3 个答案:

答案 0 :(得分:2)

一种可能(简单)的解决方案是在函数末尾添加unname函数:return(unname(B))。再次运行你的例子给出:

> insert.col(A,c(0,0),2)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    0    3    5    7    9
[2,]    2    0    4    6    8   10

如果您想避免for循环,可以使用此版本

append.cols <- function(A, x, p){
  if(p==1){
    B <- cbind(x, A)
  } 
  else if(p==ncol(A)){
    B <- cbind(A[,1:(p-1)], x, A[, p])
  } else {
    B <- cbind(A[,1:(p-1)], x, A[, (p+1):ncol(A)])
  }
  return(unname(B))
}

示例:

> append.cols(A,c(0,0),2)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    5    7    9
[2,]    2    0    6    8   10
> append.cols(A,c(0,0),5)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    5    7    0    9
[2,]    2    4    6    8    0   10

答案 1 :(得分:1)

这可能更简单。但仍然需要unname(...)

insert.col <- function(A,x,p)
{
  if (p==1) B <- cbind(x,A)
  else B <- cbind(A[,1:(p-1)],x,A[,p:ncol(A)])
  return(unname(B))
}

A=matrix(1:20,ncol=5)
x=rep(4,4)
insert.col(A,x,2)
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    1    4    5    9   13   17
# [2,]    2    4    6   10   14   18
# [3,]    3    4    7   11   15   19
# [4,]    4    4    8   12   16   20

答案 2 :(得分:1)

cbind的默认值是deparse.level = 1(虽然我对文档说的相反是什么?),它根据参数名称为你决定标签。

您可以将deparse.level = 0添加到cbind以防止这种情况(我也简化了该功能)。

insert.col2 <- function(A, x, p) cbind(A[,seq_len(p-1)], x, A[,p:ncol(A)], deparse.level = 0)

insert.col2(A,c(0,0),2)
#      [,1] [,2] [,3] [,4] [,5] [,6]
#[1,]    1    0    3    5    7    9
#[2,]    2    0    4    6    8   10

与其他2个答案和您自己的函数一样,如果您尝试使用它添加到矩阵的末尾(例如,在此示例中为p = 6),则会失败。