0

我正在使用一些与以下简单脚本有重要相似之处的代码:

scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
result <- matrix(NA, ncol=2, nrow=20)
index <- as.logical(rbinom(20,1,.2))
result[index, 1:3] <- cbind(1, scores[index,3:4])

其中 index 是一个逻辑向量,sum(index)通常大于1但偶尔可以是1or 0

脚本在以下情况下失败sum(index) == 1

> scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
> result <- matrix(NA, ncol=3, nrow=20)
> index <- c(rep(FALSE, 19),TRUE)
> result[index, 1:3] <- cbind(1, scores[index,3:4])
Error in result[index, 1:3] <- cbind(1, scores[index, 3:4]) : 
  number of items to replace is not a multiple of replacement length
> cbind(1, scores[index,3:4])
     [,1]       [,2]
[1,]    1 -0.1780255
[2,]    1 -0.6840048
> #should be:
> c(1, scores[index,3:4])
[1]  1.0000000 -0.1780255 -0.6840048

并且在哪里sum(index) ==0

> scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
> result <- matrix(NA, ncol=3, nrow=20)
> index <- rep(FALSE, 20)
> result[index, 1:3] <- cbind(1, scores[index,3:4])
Warning message:
In cbind(1, scores[index, 3:4]) :
  number of rows of result is not a multiple of vector length (arg 1)
> #cbinding to a zero-row matrix returns an error

这个问题的明显解决方案如下:

scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
result <- matrix(NA, ncol=3, nrow=20)
index <- as.logical(rbinom(20,1,.1))
if(sum(index) > 1){
    result[index, 1:3] <- cbind(1, scores[index,3:4])
}else{
    if(sum(index) ==1){
        result[index, 1:3] <- c(1, scores[index,3:4])
    }
}

但是,我对如何编写代码以避免此错误而无需编写一堆if语句的建议很感兴趣。将原子向量绑定到 nx2 矩阵或 2 长度向量 (n=1) 是否有技巧,以使结果始终是 nx3 矩阵?如果脚本可以在 n=0 时执行此操作而不会产生错误,则加分。

如果不是一个小时的调试,我就不会发现这个问题——它在批处理脚本中隐藏了相当多的功能。关于避免这种“陷阱”的编码方式有什么一般性建议吗?

4

1 回答 1

2

通常添加drop=FALSEmtx[1,]调用将避免单行提取和假定矩阵结构的后续操作出现的困难:

result[index, 1:2] <- cbind(1, scores[1, 3:4, drop=FALSE])  # no error
# Also adding a third column to avoid dimension mismatch
scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
result <- matrix(NA, ncol=3, nrow=20)
index <- as.logical(rbinom(20,1,.2))
result[index, 1:3] <- cbind(1, scores[index,3:4, drop=FALSE])

我还没有完全弄清楚您希望我们如何避免将零行对象分配给零行对象的错误。您应该改为检查length(index)==0

(真正的问题是你将一个三列矩阵分配给一个两列目标。哦,我看到你试图解决这个问题,但你仍然试图分配给维度中不存在的第三列。)

于 2012-12-12T02:09:17.350 回答