我正在使用一些与以下简单脚本有重要相似之处的代码:
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
但偶尔可以是1
or 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 时执行此操作而不会产生错误,则加分。
如果不是一个小时的调试,我就不会发现这个问题——它在批处理脚本中隐藏了相当多的功能。关于避免这种“陷阱”的编码方式有什么一般性建议吗?