在for循环中收集数据(使用与我以前不同的结构)

时间:2017-06-24 16:12:44

标签: r indexing

我知道这个问题会被问到很多。通过在循环外创建一个迭代存储观察的对象,我很乐意在for循环中收集数据。

但是,我正在进行k-fold交叉验证功能,并且从stats.stackexchange中遇到了这个不错的函数: https://stats.stackexchange.com/a/105839

  #Randomly shuffle the data
yourData<-yourData[sample(nrow(yourData)),]

#Create 10 equally size folds
folds <- cut(seq(1,nrow(yourData)),breaks=10,labels=FALSE)

#Perform 10 fold cross validation
for(i in 1:10){
    #Segement your data by fold using the which() function 
    testIndexes <- which(folds==i,arr.ind=TRUE)
    testData <- yourData[testIndexes, ]
    trainData <- yourData[-testIndexes, ]
    #Use the test and train data partitions however you desire...
}

我想我以前常常看到索引变量&#39; i&#39;在整个代码中使用。当我尝试存储某些下游变量的每次迭代时(让我们说一些线性分类器的错误分类率,存储在向量miss_class中)。它不像我以前那样工作;我只能在尝试miss_class[i]<-#relevant code within loop[i]时存储第一个迭代值。

我知道这是模糊的,没有可重现的代码,但我很欣赏一些见解。谢谢。

2 个答案:

答案 0 :(得分:0)

虽然循环可行,但如果您想避免boot::cv.glmmodelr::crossv_kfold等,一个好的组织策略是将所有内容都放在data.frame中,从索引的列表列开始每个折叠。完成后,您可以轻松lapplyMap在该列中添加基于该数据子集的新列 - 如果您愿意,甚至可以包括完整模型。一个简单的例子:

set.seed(47)

df <- data.frame(k = seq(10))

# add list column of indices
df$indices <- split(seq(nrow(iris)), 
                    sample(cut(seq(nrow(iris)), 10, labels = FALSE)))

# add models as list column
df$model <- lapply(df$indices, function(i){lm(Sepal.Length ~ ., iris, subset = i)})
# extract adjusted R^2 to new column
df$adj_r_squared <- sapply(df$model, function(m){summary(m)$adj.r.squared})

dplyr::tbl_df(df)    # base R print method gets out of hand
#> # A tibble: 10 x 4
#>        k    indices    model adj_r_squared
#>    <int>     <list>   <list>         <dbl>
#>  1     1 <int [15]> <S3: lm>     0.8824608
#>  2     2 <int [15]> <S3: lm>     0.6168011
#>  3     3 <int [15]> <S3: lm>     0.8843492
#>  4     4 <int [15]> <S3: lm>     0.8827520
#>  5     5 <int [15]> <S3: lm>     0.8651278
#>  6     6 <int [15]> <S3: lm>     0.9331991
#>  7     7 <int [15]> <S3: lm>     0.9351074
#>  8     8 <int [15]> <S3: lm>     0.8997065
#>  9     9 <int [15]> <S3: lm>     0.8915772
#> 10    10 <int [15]> <S3: lm>     0.8434274

# aggregate
data.frame(mean_r_squared = mean(df$adj_r_squared), 
           sd_r_squared = sd(df$adj_r_squared))
#>   mean_r_squared sd_r_squared
#> 1      0.8634509    0.0909918

答案 1 :(得分:0)

我在搜索答案时了解了追加功能。通过:vec&lt; -c()创建空向量后,您可以使用:vec&lt; -append(vec,info)以此格式存储来自for循环的数据。