有没有办法将输出存储在for_loop函数中?

时间:2019-04-03 12:09:41

标签: r loops

我必须计算一系列值的模型精度。我将需要创建一个for循环来馈入这些值的范围,然后将这些输出存储在一个空的数据框中。

我尝试利用自己的python经验最初创建一个空列表,并尝试遍历一系列值的for循环。

Train_Rest_Loop Dataframe:

  ground Rest_Cos_Sim
1      1         0.25
2      1         0.20
3      1         0.35
4      1         0.25
5      1         0.25
6      0         0.30


cos_sim_values <- seq(0,1, by=0.05)
Accuracy <- matrix(NA, nrow=21, ncol=2) # Empty Matrix

for (i in cos_sim_values) {
train_rest_loop['Rest_Cos_Sim'] <- ifelse(train_rest_loop$Rest_Cos_Sim >= i, 1,0)
cm_train_rest <- table(train_rest_loop$ground, train_rest_loop$Rest_Cos_Sim)
cm_train_rest <- caret :: confusionMatrix(cm_train_rest, mode = "prec_recall", positive="1") 
Accuracy[i,] <- as.vector(cm_train_rest$overall['Accuracy']) }

Error in !all.equal(nrow(data), ncol(data)) : invalid argument type

没有实际结果,因为代码无法运行,请参见上面的错误消息。

我希望得到一个精度值列表:

  cos_sim_values Accuracy
1      0.1          0.25
2      0.15         0.20
3      0.20         0.35
4      0.25         0.25
5      0.30         0.25
6      0.40         0.30

2 个答案:

答案 0 :(得分:1)

错误消息来自一行

cm_train_rest <- caret :: confusionMatrix(cm_train_rest, mode = "prec_recall", positive="1")

并说 cm_train_rest 应该具有相同的列数和行数,而不是这种情况。

您的主要问题:

Accuracy[i,] <- as.vector(cm_train_rest$overall['Accuracy'])
在您的情况下,

也将无法正常工作,因为 cos_sim_values 的值不能用作索引。

此外

train_rest_loop['Rest_Cos_Sim'] <- ifelse(train_rest_loop$Rest_Cos_Sim >= i, 1,0)

您正在覆盖 Rest_Cos_Sim 列。

也许以下内容使您更接近预期的结果:

library("caret")
library("e1071")

cos_sim_values <- seq(0,1, by=0.05)
Accuracy <- matrix(NA, nrow=length(cos_sim_values), ncol=2) # Empty Matrix

train_rest_loop <- data.frame(ground=factor(c(1,1,1,1,1,0)), Rest_Cos_Sim=c(0.25,0.20,0.35,0.25,0.25,0.30))

for (idx in 1:length(cos_sim_values)) { #use idx as an index which ranges from 1 to the length of cos_sim_values
  i <- cos_sim_values[idx]  #Get the idx'th values of cos_sim_values
  tt <- factor(ifelse(train_rest_loop$Rest_Cos_Sim >= i, 1,0), levels = c(0,1))
  cm_train_rest <- table(train_rest_loop$ground, tt)
  cm_train_rest <- caret :: confusionMatrix(cm_train_rest, mode = "prec_recall", positive="1") 
  Accuracy[idx,] <- c(i, as.vector(cm_train_rest$overall['Accuracy']))
}

答案 1 :(得分:0)

以下是在发生错误时使用lapply而不是循环和tryCatch的一种方法。
我使用as.integer(condition)而不是ifelse,因为结果是二进制10

library(caret)
library(e1071)

cos_sim_values <- seq(0, 1, by = 0.05)

result_list <- lapply(cos_sim_values, function(csvals){
  trl[['Rest_Cos_Sim']] <- as.integer(train_rest_loop$Rest_Cos_Sim >= csvals)
  trl[['Rest_Cos_Sim']] <- factor(trl[['Rest_Cos_Sim']], levels = 0:1)
  cm_train_rest <- table(trl)
  cm_train_rest <- tryCatch(confusionMatrix(cm_train_rest, mode = "prec_recall", positive = "1"),
                            error = function(e) e)
})

ok <- !sapply(result_list, inherits, "error")
result_list[ok]

Accuracy <- sapply(result_list[ok], '[[', 'overall')[1, ]
Accuracy
# [1] 0.8333333 0.8333333 0.8333333 0.8333333 0.8333333
# [6] 0.6666667 0.3333333 0.1666667 0.1666667 0.1666667
#[11] 0.1666667 0.1666667 0.1666667 0.1666667 0.1666667
#[16] 0.1666667 0.1666667 0.1666667 0.1666667 0.1666667
#[21] 0.1666667

数据。

train_rest_loop <- read.table(text = "
  ground Rest_Cos_Sim
1      1         0.25
2      1         0.20
3      1         0.35
4      1         0.25
5      1         0.25
6      0         0.30
", header = TRUE)