0

我正在使用 R 并且需要创建检查矩阵尺寸是否为 3x3 的代码。我被困在if()用于检查nrowand的正确代码上ncol。非常感谢任何帮助或建议。

localSmoother <- function(myMatrix = matrix(), 
  smoothingMatrix = matrix(1, nrow = 3, ncol = 3)) 
{ 
  if(class(smoothingMatrix) != "matrix") stop ("smoothingMatrix must be a matrix.")  
  if(ncol(smoothingMatrix) != "3" & if(nrow(smoothingMatrix) != "3") 
  stop ("smoothingMatrix must have dimensions of 3x3") 

  print(myMatrix) # see what myMatrix is.
  print(smoothingMatrix) # see what smoothingMatrix is.
  return(matrix(, nrow = 3, ncol = 3))
}

# # TEST the CODE:
localSmoother(myMatrix = diag(x = 2, nrow = 5, ncol = 5), smoothingMatrix = matrix(2, nrow = 5, ncol = 3))

# # Error in localSmoother(myMatrix = diag(x = 2, nrow = 5, ncol = 5), smoothingMatrix = matrix(2,  : 

# # smoothingMatrix must be 3x3
4

2 回答 2

2

最直接的是,您if的条件中有两个。你应该只有一个。

if(ncol(smoothingMatrix) != "3" & if(nrow(smoothingMatrix) != "3")
## should be
if(ncol(smoothingMatrix) != "3" & nrow(smoothingMatrix) != "3")

接下来,您的逻辑询问何时行数不是 3并且列数不是 3。if如果您的维度是c(5,4),则此条件按预期工作(返回 TRUE 并遵循块中的 stop 语句),但如果您的维度是c(5,3)

x <- matrix(1:20,nrow=5)
dim(x)
# [1] 5 4
ncol(x) != "3" & nrow(x) != "3" 
# [1] TRUE

x <- matrix(1:12,nrow=3)
dim(x)
# [1] 3 4
ncol(x) != "3" & nrow(x) != "3" 
# [1] FALSE

我将改为使用以下任一等效行:

if(!(ncol(smoothingMatrix) == 3 && nrow(smoothingMatrix) == 3))
## is the same as
if(ncol(smoothingMatrix) != 3 || nrow(smoothingMatrix) != 3)

注意两点:

  1. 我使用的是逻辑运算符&&||而不是矢量化运算符&and |。尝试c(TRUE, FALSE) & TRUEc(TRUE, FALSE) && TRUE..
  2. 我使用的是数字形式3而不是字符"3"。R 会将数字强制转换为字符,因此相等性测试在这里有效,但在其他情况下可能会绊倒你。

比较矩阵的维度可能更容易:

if(!isTRUE(all.equal(dim(smoothingMatrix),c(3L,3L))))

(isTRUE是必需的,因为all.equal返回一个TRUE或一个描述差异的字符向量。观察它all.equal(1,0)不会返回FALSE,而是一个描述差异的字符向量。如果相等不成立,那么if周围的任何语句都会抛出错误。)all.equal

all.equal(1,0)
# [1] "Mean relative difference: 1"

if(all.equal(1,0)) print(TRUE) 
# Error in if (all.equal(1, 0)) print(TRUE) : 
#   argument is not interpretable as logical
于 2013-09-17T18:33:13.173 回答
1

@Blue Magister 的回答很好,有很好的解释,请先去那里。

对于您的特定任务,您可能会发现该stopifnot功能很有用。从?stopifnot

stopifnot(...)如果 ... 中的任何表达式不全为 TRUE,则调用 stop,产生一条错误消息,指示 ... 的第一个元素不为真。

您的代码可能是

stopifnot(is.matrix(smoothingMatrix),
          ncol(smoothingMatrix) == 3,
          nrow(smoothingMatrix) == 3)

缺点是错误消息不太有用,优点是您不必自己编写它们,并且代码很好而且干净。

于 2013-09-17T19:44:49.437 回答