我想在现有矩阵中插入一列。我写了以下函数:
> 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?有没有优雅的方式实现这个?
答案 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
),则会失败。