2015-08-13 63 views
1

我正在處理10個訓練數據集train1到train10,並且希望用1個代碼塊重複1到10的以下語句:在list2serv中合併多個函數參數(lapply(),)

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()比循環更適合。我的代碼:

# 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(),我打算在值進行讀取的一個功能相混淆,B ,c,d參數,但我不知道下一步如何繼續。

有什麼建議嗎?

回答

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 
}) 
+0

非常好,謝謝。我爲train1-train10列表添加了「train < - lapply(1:10,function(x){paste0(」train「,x)})」。我收到一條錯誤消息:當我運行代碼時,「$ y:$運算符中的錯誤對於原子向量無效」 – RobertF

+0

@RobertF「train」應該是實際訓練數據集的列表,如果我正在閱讀此權限。所以,如果你把它們全部放在你的全球環境中,我想'train < - mget(paste0(「train」,1:10))' – jenesaisquoi

+0

好多了,謝謝!該程序似乎運行正常,雖然它不保存b,c和d的輸出數據幀。如果你想返回多個值,將它們包裝在一個列表中,也就是'list(a = a,b = b,c = c,d = d)' – RobertF

1

我們可以用下面的代碼實現這一點。

# 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個模型的係數並將它們存儲在列表中。

+0

感謝Vlo,這太棒了!我將不得不對自己進行有關%>%運算符的教育。不幸的是,我收到一條錯誤消息:'錯誤:運行代碼後找不到函數「%>%」。 – RobertF

+0

@RobertF你運行'庫(dplyr)'成功了嗎? – Vlo

+0

是的,就是這樣 - 代碼完美工作。再次感謝 – RobertF