2

我正在尝试应用我在这里找到的解决方案来生成机器学习模型:

这是一个虚拟数据集:

data_pred <- data.frame(x1 = 1:10, x2 = 11:20, x3 = 21:30)
data_resp <- data.frame(y1 = c(1:5, NA, 7:10), y2 = c(NA, 2, NA, 4:10))

这是我在使用包时在测量响应的每一列中对for()预测变量进行建模的循环方法:data_preddata_respcaret

# data_pred contains predictors
# data_resp contains one column per measurement
# 1 matching row per observation in both data_pred and data_resp

for (i in 1:ncol(data_resp)) {

   train(x = data_pred[!is.na(data_resp[, i]), ],
         y = data_resp[!is.na(data_resp[, i], i],
         ... )
}

现在我正在尝试对 做同样的事情lapply,我认为这有很多优点。我在即时翻译!is.na()标准时遇到问题,因此我只为每个响应使用非 NA 案例建模。lapply这是我测试该方法的初始函数:

rf_func <- function(y) {
  train(x = data_pred,
        y = y,
        method = "rf",
        tuneGrid = data.frame(.mtry = 3:6),
        nodesize = 3,
        ntrees = 500,
        trControl = trControl) }

然后创建一个空列表来存储结果并将函数应用于data_resp

models <- list(NULL)
models$rf <- lapply(as.list(data_resp), rf_func)

这很好用,因为randomForest可以处理NAs,但其他方法不能,所以我需要从每个data_resp元素中删除这些行以及从我的预测变量中删除相应的行。

我试过这个没有成功:

train(x = data_pred_scale[!is.na(y), ],
      y = y[!is.na(y)],
      ... }

我也试过y[[!is.na(y)]]

如何将 data.frame 方法 ( df[!is.na(df2), ]) 转换为lapply

4

2 回答 2

3

几种不同的方法来解决它。一个简单的方法是使用匿名函数:

 lapply(data_resp, function(x) rf_func(x[!is.na(x)]))
于 2013-07-22T23:57:13.627 回答
0

在摆弄我的一个元素as.list(data_frame)来模拟lapply将要传递的内容时,我想出了这个,我认为这是有效的:

rf_func <- function(y) {
  train(x = data_pred_scale[!(unlist(lapply(y, is.na))), ], 
        y = y[!(unlist(lapply(y, is.na)))], 
        method = "rf",
        tuneGrid = data.frame(.mtry = 3:6),
        nodesize = 3,
        ntrees = 500,
        trControl = trControl) }

models$rf <- lapply(as.list(data_resp), rf_func)

似乎确实有效。我 [hackishly] 将非NA数据集与trainingData每个caret模型中的结果进行了比较,如下所示:

nas <- NULL
for(i in 1:ncol(data_resp)) {nas <- c(nas, length(data_resp[!is.na(data_resp[, i]), i]))}

model_nas <- NULL
for(i in 1:length(nas)) {model_nas <- c(model_nas, nrow(models$rf[[i]]$trainingData))}

identical(nas, model_nas)
[1] TRUE

那么,y[!unlist(lapply(y, is.na)))]做这种事情的最好/最优雅的方式是不是很丑......


编辑:根据@Ricardo Saporta 的回答,我想出了这个(对于退伍军人来说可能很明显,但请耐心等待):

rf_func <- function(x, y) {
  train(x = x,
        y = y,
        method = "rf",
        tuneGrid = data.frame(.mtry = 3:6),
        nodesize = 3,
        ntrees = 500,
        trControl = trControl) }

models$rf <- lapply(data_resp, function (y) {
  rf_func(data_pred_scale[!is.na(y), ], y[!is.na(y)] ) 
  }
)

还有更好的方法,还是相当不错的?(当然比我上面第一次搞砸的更漂亮。)

于 2013-07-22T23:57:58.797 回答