【问题标题】:R: Saving the Results of a LoopR:保存循环的结果
【发布时间】:2021-05-04 15:50:56
【问题描述】:

我正在使用 R 编程语言。我正在学习循环以及如何存储循环的结果。例如,我编写了以下循环函数的代码(生成随机数据并适合不同的决策树):

#load libraries    
    library(caret)
library(rpart)

#generate data

a = rnorm(1000, 10, 10)

b = rnorm(1000, 10, 5)

c = rnorm(1000, 5, 10)

group <- sample( LETTERS[1:2], 1000, replace=TRUE, prob=c(0.5,0.5) )
group_1 <- 1:1000

#put data into a frame
d = data.frame(a,b,c, group, group_1)

d$group = as.factor(d$group)

#place results in table
#final_table = matrix(1, nrow = 10, ncol=10)


e <- d



vec1 <- sample(200:300, 5)
vec2 <- sample(400:500,5)
vec3 <- sample(700:800,5)

for (i in seq_along(vec1)) { 
    for (j in seq_along(vec2)) {
        for (k in seq_along(vec3)) {
            # d <- e
            d$group_2 = as.integer(ifelse(d$group_1 < vec1[i] , 0, ifelse(d$group_1 >vec1[i]  & d$group_1 < vec2[j] , 1, ifelse(d$group_1 >vec2[j]  & d$group_1 < vec3[k] , 2,3))))
            
            
            
            
            d$group_2 = as.factor(d$group_2)
            
            fitControl <- trainControl(## 10-fold CV
                method = "repeatedcv",
                number = 2,
                ## repeated ten times
                repeats = 1)
            
            TreeFit <- train(group_2 ~ ., data = d[,-5],
                             method = "rpart",
                             trControl = fitControl)
            
            pred <- predict(
                TreeFit,
                d[,-5])
            
            con <- confusionMatrix(
                d$group_2,
                pred) 
            
            #update results into table
            #final_table[i,j] = con$overall[1]
            acc=c(vec1[i],vec2[j],vec3[k],con$overall[1])
            print(acc)
            
            
        }
    }
}

我有兴趣将“acc”的结果保存到表格(或数据框)中。我可以打印“acc”的所有值,但是当我正式查看“acc”的结果时:只显示最后一行。

我的问题:是否可以获取整个打印输出(即“acc”)并将其存储到表格中?

谢谢

【问题讨论】:

    标签: r loops random iteration


    【解决方案1】:

    您在此处发布的非常好的示例。要启动您的数据框,我们可以添加:

    #place results in table
    final_table = data.frame(vec1=double(),vec2=double(),vec3=double(),Accuracy=double())
    

    我们可以将acc 的输出存储到其中:

    #update results into table
    acc=c(vec1[i],vec2[j],vec3[k],con$overall[1])
    final_table<-rbind(final_table,acc)
    

    【讨论】:

    • 感谢您的回答!我会试试这个!
    • 我在这里发布了一个关于限制循环大小的相关问题。如果可以的话,你能看一下吗? stackoverflow.com/questions/65985782/… 谢谢!
    【解决方案2】:

    您可以使用expand.grid 创建vec1vec2vec3 的所有可能组合,并在数据框中的每次迭代中保存con$overall[1]

    library(caret)
    library(rpart)
    
    #generate data
    
    a = rnorm(1000, 10, 10)
    b = rnorm(1000, 10, 5)
    c = rnorm(1000, 5, 10)
    group <- sample( LETTERS[1:2], 1000, replace=TRUE, prob=c(0.5,0.5))
    group_1 <- 1:1000
    
    #put data into a frame
    d = data.frame(a,b,c, group, group_1)
    d$group = as.factor(d$group)
    
    e <- d
    vec1 <- sample(200:300, 5)
    vec2 <- sample(400:500,5)
    vec3 <- sample(700:800,5)
    z <- 0
    df <- expand.grid(vec1, vec2, vec3)
    df$Accuracy <- NA
    
    for (i in seq_along(vec1)) { 
      for (j in seq_along(vec2)) {
        for (k in seq_along(vec3)) {
          # d <- e
          d$group_2 = as.integer(ifelse(d$group_1 < vec1[i] , 0, ifelse(d$group_1 >vec1[i]  & d$group_1 < vec2[j] , 1, ifelse(d$group_1 >vec2[j]  & d$group_1 < vec3[k] , 2,3))))
          
          d$group_2 = as.factor(d$group_2)
          
          fitControl <- trainControl(## 10-fold CV
            method = "repeatedcv",
            number = 2,
            ## repeated ten times
            repeats = 1)
          
          TreeFit <- train(group_2 ~ ., data = d[,-5],
                           method = "rpart",
                           trControl = fitControl)
          
          pred <- predict(
            TreeFit,
            d[,-5])
          
          con <- confusionMatrix(
            d$group_2,
            pred) 
          
          #update results into table
          #final_table[i,j] = con$overall[1]
          z <- z + 1
          df$Accuracy[z] <- con$overall[1]
        }
      }
    }
    
    head(df)
    
    #  Var1 Var2 Var3 Accuracy
    #1  300  492  767    0.299
    #2  202  492  767    0.299
    #3  232  492  767    0.299
    #4  293  492  767    0.376
    #5  231  492  767    0.299
    #6  300  435  767    0.331
    

    【讨论】:

    • 我真的很喜欢这个答案!这样,我不需要为最终表格定义行数和列数。谢谢!
    • 我在这里发了一个相关的问题:stackoverflow.com/questions/65985782/…你有时间可以看看吗?谢谢
    【解决方案3】:

    还有一种替代方法,它将每次迭代的结果保存为列表的元素,然后将结果组合起来。通过在循环开始之前分配列表,我们可以避免代价高昂的growing in a loop。此外,这种方法在循环顺序发生变化的情况下也很稳健。

    #load libraries    
    library(caret)
    library(rpart)
    
    #generate data
    
    a = rnorm(1000, 10, 10)
    
    b = rnorm(1000, 10, 5)
    
    c = rnorm(1000, 5, 10)
    
    group <- sample( LETTERS[1:2], 1000, replace=TRUE, prob=c(0.5,0.5) )
    group_1 <- 1:1000
    
    #put data into a frame
    d = data.frame(a,b,c, group, group_1)
    
    d$group = as.factor(d$group)
    
    #place results in table
    #final_table = matrix(1, nrow = 10, ncol=10)
    
    e <- d
    
    vec1 <- sample(200:300,2)
    vec2 <- sample(400:500,2)
    vec3 <- sample(700:800,2)
    
    result_list <- vector("list", length(vec1)*length(vec2)*length(vec3))
    result_count <- 0L
    
    for (i in seq_along(vec1)) { 
      for (j in seq_along(vec2)) {
        for (k in seq_along(vec3)) {
          # d <- e
          d$group_2 = as.integer(ifelse(d$group_1 < vec1[i] , 0, ifelse(d$group_1 >vec1[i]  & d$group_1 < vec2[j] , 1, ifelse(d$group_1 >vec2[j]  & d$group_1 < vec3[k] , 2,3))))
          d$group_2 = as.factor(d$group_2)
          
          fitControl <- trainControl(## 10-fold CV
            method = "repeatedcv",
            number = 2,
            ## repeated ten times
            repeats = 1)
          
          TreeFit <- train(group_2 ~ ., data = d[,-5],
                           method = "rpart",
                           trControl = fitControl)
          
          pred <- predict(
            TreeFit,
            d[,-5])
          
          con <- confusionMatrix(
            d$group_2,
            pred) 
          
          #update results into table
          #final_table[i,j] = con$overall[1]
          acc=c(vec1=vec1[i],vec2=vec2[j],vec3=vec3[k],con$overall[1])
          result_count <- result_count + 1L
          result_list[[result_count]] <- acc
          print(acc)
        }
      }
    }
    
    (final_table <- do.call(rbind, result_list))
     
    

    【讨论】:

    • 感谢您的回答!我有一个相关的问题想问(我会发布)
    • 我在这里发布了一个关于限制循环大小的问题:stackoverflow.com/questions/65985782/… 如果可能的话,你能看一下吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    相关资源
    最近更新 更多