在 list2serv(lapply(),) 中组合多个函数参数

Combining multiple function arguments inside list2serv(lapply(),)

我正在处理 10 个训练数据集,train1 到 train10,我想用一个代码块对 1 到 10 重复以下语句:

  train_y_1 <- c(train1$y)
  train1$y <-NULL
  train_x_1 <- data.matrix(train1) 
  olsfit_1 <- cv.glmnet(y=train_y_1, x=train_x_1, alpha=1, family="gaussian")

我在论坛上看到 lapply() 比 for 循环更可取。我的代码:

# Create empty data frames and list (to be populated with values in main program) 
list2env(setNames(lapply(1:10, function(i) data.frame()), paste0('train_y_', 1:10)), envir=.GlobalEnv)
list2env(setNames(lapply(1:10, function(i) data.frame()), paste0('train_x_', 1:10)), envir=.GlobalEnv)
list2env(setNames(lapply(1:10, function(i) list()), paste0('lasso_', 1:10)), envir=.GlobalEnv)

# Create y and x input matrices and run ten lasso regressions
  list2env(lapply(mget(paste0('train', 1:10)), mget(paste0('train_y_', 1:10)), mget(paste0('train_x_', 1:10)), mget(paste0('lasso_', 1:10)), 
  function(a,b,c,d) 
  {
    b <- c(a$y);
    a$y <- NULL;
    c <- data.matrix(a); 
    d <- cv.glmnet(y=b, x=c, alpha=1, family="gaussian");
  }), envir=.GlobalEnv)

产生错误消息:

Error in match.fun(FUN) : 
  'mget(paste0("train_y_", 1:10))' is not a function, character or symbol

所以看起来 R 被四个 mget() 函数弄糊涂了,我打算在 a、b、c、d 参数的值中读取这些函数,但我不确定下一步如何进行。

有什么建议吗?

您希望尽可能将所有数据保存在列表中,避免一堆变量污染全局环境。这未经测试, train 丢失,但应该是您的火车数据的类似列表。然后,你可以做类似的事情,

trainy <- setNames(lapply(1:10, function(i) data.frame()), paste0('train_y_', 1:10))
trainx <- setNames(lapply(1:10, function(i) data.frame()), paste0('train_x_', 1:10))
lasso <- setNames(lapply(1:10, function(i) list()), paste0('lasso_', 1:10))

f <-   function(a,b,c,d) {
    b <- c(a$y);
    a$y <- NULL;
    c <- data.matrix(a); 
    d <- cv.glmnet(y=b, x=c, alpha=1, family="gaussian");
}

mapply(f, train, trainy, trainx, lasso, SIMPLIFY=F)

不过,由于您的列表只是初始化变量,您可能只想循环 (apply) 训练数据列表,

lapply(train, function(x) {
    ...        # the statements you want to repeat
    list(...)  # return a list of the three data.frames
})

我们可以用下面的代码来实现。

# Load libraries
library(dplyr);library(glmnet)
# Gather all the variables in global into a list
fit = mget(paste0("train", 1:10), envir = .GlobalEnv) %>%
# Pipe each element of the list into `cv.glmnet` function     
      lapply(function(dat) {cv.glmnet(y = dat$y,
                            x = data.matrix(dat %>% mutate(y = NULL)),
                            alpha = 1,
                            family = "gaussian")})

您的输出将整齐地存储在 fit 中,这是一个包含 10 个元素的列表。您可以使用 fit[[i]] 调用每个元素。例如 coef(fit[[1]]) 提取 train1 的系数,lapply(fit, coef) 提取所有 10 个模型的系数并将它们存储在列表中。