8

我很好奇R是否能够将对象放入向量/列表/数组/等中。我正在使用 randomforest 包来处理较大数据的子集,并希望将每个版本存储在列表中。这将类似于:

answers <- c()
for(i in 1:10){
x <- round((1/i), 3)
answers <- (rbind(answers, x))
}

理想情况下,我想做这样的事情:

answers <- c()
for(i in 1:10){
RF <- randomForest(training, training$data1, sampsize=c(100), do.trace=TRUE, importance=TRUE, ntree=50,,forest=TRUE)
answers <- (rbind(answers, RF))
}

这种工作,但这是单个 RF 对象的输出:

> RF 

Call:
 randomForest(x = training, y = training$data1, ntree = 50, sampsize = c(100), importance = TRUE, do.trace = TRUE,      forest = TRUE) 
               Type of random forest: regression
                     Number of trees: 10
No. of variables tried at each split: 2

          Mean of squared residuals: 0.05343956
                    % Var explained: 14.32

虽然这是“答案”列表的输出:

> answers 
   call       type         predicted      mse        rsq        oob.times      importance importanceSD
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
RF Expression "regression" Numeric,150000 Numeric,10 Numeric,10 Integer,150000 Numeric,16 Numeric,8   
   localImportance proximity ntree mtry forest  coefs y              test inbag
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 
RF NULL            NULL      10    2    List,11 NULL  Integer,150000 NULL NULL 

有谁知道如何存储所有 RF 对象或调用它们以便存储的信息与单个 RF 对象相同?感谢您的建议。

4

4 回答 4

11

不要一次增长向量或列出一个元素。预先分配它们并将对象分配给特定部分:

answers <- vector("list",10)
for (i in 1:10){
    answers[[i]] <- randomForest(training, training$data1, sampsize=c(100), 
                                 do.trace=TRUE, importance=TRUE, ntree=50,
                                 forest=TRUE)
}

附带说明一下,rbinding 向量不会创建另一个向量或列表。如果您在第一个示例中检查输出,您会发现它是一个包含一列的矩阵。这解释了您在尝试将rbindrandomForest 对象放在一起时观察到的奇怪行为。

于 2011-10-19T02:46:32.800 回答
5

使用lapply

lapply(1:10,function(i) randomForest(<your parameters>))

你会得到一个随机森林对象的列表;然后,您可以使用运算符访问其中的第 i 个[[]]

于 2011-10-19T09:09:04.987 回答
3

初始化一个列表:

mylist <- vector("list")  # technically all objects in R are vectors

添加到它:

new_element <- 5
mylist <- c(mylist, new_element)

@joran 关于预分配的建议在列表很大时是相关的,但在列表很小时并不完全必要。您还可以访问您在原始代码中构建的矩阵。它看起来有点奇怪,但信息都在那里。例如,该列表矩阵的第一个元素可以通过以下方式恢复:

answers[1, ]
于 2011-10-19T03:04:40.050 回答
0

其他答案提供了将随机森林对象存储在 a 中的解决方案list,但它们没有解释它们为什么起作用。

正如@42- 所暗示的,这不是解决这里问题的预分配步骤。

真正的问题是一个randomForest对象基本上是一个list(检查is.list(randomForest(...))。当您编写如下语句时:

list_of_rf = c()                                       # ... or list_of_rf = NULL
list_of_rf = rbind(list_of_rf, randomForest(...))      # ... or list_of_rf = c(list_of_rf, randomForest(...))

您实际上是在要求将一个空对象与一个列表连接起来。此语句不会生成长度为 1 的列表(随机森林模型),而是生成包含所有随机森林模型组件的列表!您可以通过在 R 控制台中输入来验证这一点:

> 长度(list_of_rf)

[1] 19

有几种方法可以强制 R 执行您想要的操作:

  1. 列表中的显式矫揉造作(参见@joran 的回答,虽然不需要预先分配):

    list_of_rf = NULL
    list_of_rf[[1]] = randomForest(...)
    
  2. lapply(或类似的)建立列表(cf @mbq 答案):

    list_of_rf = lapply(..., function(i) randomForest(...))
    
  3. 将随机森林封装在一个列表中,在连接过程中将对其进行简化:

    list_of_rf = NULL
    list_of_rf = c(list_of_rf, list(randomForest(...)))
    

最后,如果您犯了一个错误并取消了您的 randomForest 模型,该模型需要花费 10 个小时来计算,请不要担心,您仍然可以按如下方式恢复它:

list_of_rf = NULL
list_of_rf = c(list_of_rf, randomForest(...)) # oups, mistake
rf = as.vector(list_of_rf)[1:19]
class(rf) = 'randomForest'
于 2015-12-10T01:42:08.757 回答