R 代码警告:要替换的项目数不是替换长度的倍数

R Code Warning: number of items to replace is not a multiple of replacement length

提问人:JTruant 提问时间:10/18/2023 更新时间:10/18/2023 访问量:21

问:

从鸢尾花数据集中,我创建了以下混淆矩阵:enter image description here

在尝试使用一对多策略执行多类分类时,我提出了以下 R 代码:

mtrx <- matrix(c(10,0,0,0,10,1,0,0,9), ncol = 3)
rownames(mtrx) <- c("setosa","veriscolor", "virginica")
colnames(mtrx) <- c("setosa", "versicolor", "virginica")
cat <- colnames(mtrx)

for(n in 1:length(cat)) {
  current <- cat[n]
  binaryConMat <- mtrx
  binaryConMat[binaryConMat != 0] <- ifelse(rownames(binaryConMat) == current, 1, 0)
  
  print(binaryConMat)
  
  TP <- binaryConMat[n, n]
  FN <- sum(binaryConMat[n,]) - TP
  FP <- sum(binaryConMat[,n]) - TP
  TN <- sum(diag(binaryConMat)) - TP
  
  sensitivity <- ifelse((TP + FN) == 0, 0, TP / (TP + FN))
  specificity <- ifelse((TN + FP) == 0, 0, TN / (TN+FP))
  precision <- ifelse((TP + FP) == 0, 0, TP / (TP + FP))
  
  cat("Class:", current, "\n")
  cat("Sensitivity:", round(sensitivity, 2), "\n")
  cat("Specificity:", round(specificity, 2), "\n")
  cat("Precision:", round(precision, 2), "\n")
  cat("\n")
}

accuracy <- sum(diag(mtrx))/sum(mtrx)
cat("Overall Accuracy:",round(accuracy, 2), "\n")

但是,这会导致在运行代码时出现以下错误:

Warning: number of items to replace is not a multiple of replacement length

我已将问题隔离到以下代码行:

binaryConMat[binaryConMat != 0] <- ifelse(rownames(binaryConMat) == current, 1, 0)

但是,我不确定这个问题的合适解决方案是什么。我该怎么做才能解决此错误?

R 数据挖掘 混淆矩阵

评论


答:

1赞 Rui Barradas 10/18/2023 #1

这是更正的问题代码。
除了数据创建代码(我认为现在更简单)之外,更改都记录在注释中。

mtrx <- matrix(c(10,0,0,0,10,1,0,0,9), ncol = 3)
catg <- c("setosa","veriscolor", "virginica")
rownames(mtrx) <- catg
colnames(mtrx) <- catg

for(n in seq_along(catg)) {
  current <- catg[n]
  binaryConMat <- mtrx
  # use the logical values directly since they alreay
  # are FALSE/TRUE, meaning, 0/1
  cond1 <- binaryConMat != 0
  cond2 <- rownames(binaryConMat) == current
  # the square brackets in binaryConMat[] are meant
  # to preserve the shape of binaryConMat, a matrix
  binaryConMat[] <- as.integer(cond1 & cond2)

  print(binaryConMat)
  
  TP <- binaryConMat[n, n]
  FN <- sum(binaryConMat[n,]) - TP
  FP <- sum(binaryConMat[,n]) - TP
  TN <- sum(diag(binaryConMat)) - TP
  
  sensitivity <- ifelse((TP + FN) == 0, 0, TP / (TP + FN))
  specificity <- ifelse((TN + FP) == 0, 0, TN / (TN+FP))
  precision <- ifelse((TP + FP) == 0, 0, TP / (TP + FP))
  
  cat("Class:", current, "\n")
  cat("Sensitivity:", round(sensitivity, 2), "\n")
  cat("Specificity:", round(specificity, 2), "\n")
  cat("Precision:", round(precision, 2), "\n")
  cat("\n")
}
#>            setosa veriscolor virginica
#> setosa          1          0         0
#> veriscolor      0          0         0
#> virginica       0          0         0
#> Class: setosa 
#> Sensitivity: 1 
#> Specificity: 0 
#> Precision: 1 
#> 
#>            setosa veriscolor virginica
#> setosa          0          0         0
#> veriscolor      0          1         0
#> virginica       0          0         0
#> Class: veriscolor 
#> Sensitivity: 1 
#> Specificity: 0 
#> Precision: 1 
#> 
#>            setosa veriscolor virginica
#> setosa          0          0         0
#> veriscolor      0          0         0
#> virginica       0          1         1
#> Class: virginica 
#> Sensitivity: 0.5 
#> Specificity: 0 
#> Precision: 1

accuracy <- sum(diag(mtrx))/sum(mtrx)
cat("Overall Accuracy:",round(accuracy, 2), "\n")
#> Overall Accuracy: 0.97

创建于 2023-10-17 with reprex v2.0.2