【问题标题】:Combining multiple function arguments inside list2serv(lapply(),)在 list2serv(lapply(),) 中组合多个函数参数
【发布时间】:2015-08-13 19:25:47
【问题描述】:

我正在处理从 train1 到 train10 的 10 个训练数据集,并希望使用单个代码块对 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 对我打算读取 a、b、c、d 参数值的四个 mget() 函数感到困惑,但我不确定下一步如何进行。

有什么建议吗?

【问题讨论】:

    标签: r function lapply


    【解决方案1】:

    您希望尽可能将所有数据保存在列表中,避免使用一堆变量污染全局环境。这未经测试,并且缺少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
    })
    

    【讨论】:

    • 太好了,谢谢。我为 train1-train10 列表添加了“train
    • @RobertF train 应该是您的实际训练数据集的列表,如果我没看错的话。所以,如果你在你的全球环境中拥有所有这些,我想像train &lt;- mget(paste0("train", 1:10))
    • 好多了,谢谢!该程序似乎运行良好,尽管它没有保存 b、c 和 d 的输出数据帧。
    • @RobertF 在你的函数中,f,如果你想返回多个值,将它们包装在一个列表中,即list(a=a, b=b, c=c, d=d)
    • 知道了,非常感谢。
    【解决方案2】:

    我们可以使用以下代码来实现这一点。

    # 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 个模型的系数并将它们存储在一个列表中。

    【讨论】:

    • 感谢 Vlo,这太棒了!我将不得不对 %>% 运算符进行自我教育。不幸的是,在运行您的代码后,我收到一条错误消息:'错误:找不到函数“%>%”'。
    • @RobertF 你成功运行library(dplyr)了吗?
    • 是的 - 代码运行良好。再次感谢
    猜你喜欢
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    • 2019-08-10
    相关资源
    最近更新 更多