lapply 在使用不同列索引的数据框列表上

lapply on dataframe list using different column index

我正在尝试使用 caret 包对数据框列表进行特征选择。我有不同的数据框,但最后 6 列是相同的。当我尝试在单个 df 上应用模型时,它工作正常

# For a single dataframe
mx.chem # the name of my single dataframe
#define the control   
mx.control <- rfeControl(functions=rfFuncs, method = "cv", number = 10) 
# run the rfe     
mx.results <- rfe(mx.chem[,1:22], mx.chem[,23], sizes = c(1:22), rfeControl = mx.control)
print(mex.results)

但我的问题是当我尝试在 df 列表上使用 lapply 时。我现在的代码是

 require(mlbench)
 require(caret)
 mylist # is a df list containing 3 df 
  for (i in 1:3) {
  my.control <- rfeControl(functions=rfFuncs, method = "cv", number = 10)  # define the control
  longdata <- length(i)-6
  idxindustry <- longdata +1
  my.results <- lapply(mylist, function(x) rfe ( x[,1:longdata], x[,idxindustry], data = x, sizes =c(1:longdata), rfeControl = my.control))
  }

我不确定我是否正确使用了列索引。有谁知道如何修复以使我的代码正常工作。谢谢

您的代码与您的想法不符。 length(i) 将始终为 1,因为 i 是您的循环索引并取值 1 到 3。您的意思是:

length(mylist[[i]])

注意双括号。这就是您 select 列表中的元素的方式,在本例中为数据框。如果你使用单括号,你会得到一个包含你想要的元素的列表。

但这仍然不是您要实现的目标。如果您要更改代码中的那一行,则会有 2 个循环:

  • 每次基于单个数据帧创建 longdataidxindustry 的外循环。
  • 一个内部 lapply 循环,在所有三个数据帧上使用 longdataidxindustry 的值。

请记住,lapply 获取列表中的每个元素并将其作为第一个参数传递给您指定的函数。所以你可以像这样在单个 lapply 中完成此操作:

my.control <- rfeControl(functions=rfFuncs, method = "cv", number = 10)  

my.results <- lapply(mylist, function(x){
# x becomes one of the data frames in the list mylist here, so you can
# treat it like a data frame in the code below
  longdata <- length(x) - 6
  idxindustry <- longdata +1
  rfe( x[,1:longdata], x[,idxindustry], data = x, 
      sizes =c(1:longdata), rfeControl = my.control)
})

然后你 运行 rfelongdataidxindustry 基于手头的数据框。请注意,为了提高性能,我将对 rfeControl 的调用置于 lapply 循环之外。

这里有两种可能的方法:

#Using lapply
mx.control <- rfeControl(functions=rfFuncs, method = "cv", number = 10) 
rfe.lst <- lapply(mylist, 
           function(x) {
               longdata <- ncol(x)-6
               rfe ( x[,1:longdata], x[,longdata + 1], 
                         sizes =c(1:longdata), 
                         rfeControl = mx.control)
               })

#For loop
mx.control <- rfeControl(functions=rfFuncs, method = "cv", number = 10) 
rfe.lst <- vector("list", 3)
for(i in 1:3) {
  longdata <- ncol(mylist[[i]])-6
  rfe.lst[[i]] <- rfe(mylist[[i]][,1:longdata], x[,longdata + 1],
      sizes=c(1:longdata),
      rfeControl=mx.control)
}