使用lapply和!is.na到R中的子集列表向量

时间:2013-07-22 23:29:56

标签: r subset lapply na

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

这是一个虚拟数据集:

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_pred包在[{1}}中对每个测量回复列中data_resp的预测变量进行建模:

caret

现在我正在尝试对# 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标准的问题,因此我只针对每个响应建模非NA案例。这是我测试!is.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,但其他方法不能,所以我需要从每个NA元素中删除这些行以及我的预测变量中的相应行

我尝试了这个没有成功:

data_resp

我也试过train(x = data_pred_scale[!is.na(y), ], y = y[!is.na(y)], ... }

如何将data.frame方法(y[[!is.na(y)]])翻译为df[!is.na(df2), ]

2 个答案:

答案 0 :(得分:2)

有几种不同的方法可以解决这个问题。一个简单的方法是使用匿名函数:

 lapply(data_resp, function(x) rf_func(x[!is.na(x)]))

答案 1 :(得分: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)] ) 
  }
)

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