问题 R:lapply函数 - 跳过当前函数循环


我在多个文件列表中使用lapply函数。有没有办法我可以跳过当前文件上的函数而不返回任何内容,只是跳到文件列表中的下一个文件?

确切地说,我有一个检查条件的if语句,如果语句返回FALSE,我想跳到下一个文件。


7412
2017-07-21 15:24


起源

您可以使用条件选择列表的子集,并将此子集存储在您提供的单独变量中 lapply。 - RHertel
@RHertel由于他们正在处理文件列表而不是已经在RAM中的数据,因此他们不太可能拥有预先对文件进行子集化的信息。 - Dean MacGregor


答案:


lapply 将始终返回与列表长度相同的列表 X 提供。您可以简单地将项目设置为稍后可以过滤掉的项目。

例如,如果你有这个功能 parsefile

parsefile <-function(x) {
  if(x>=0) {
    x
  } else {
    NULL
  }
}

然后你在向量上运行它 runif(10,-5,5)

result<-lapply(runif(10,-5,5), parsefiles)

然后你会让你的清单充满答案和 NULL小号

你可以将其子集化 NULL通过做...

result[!vapply(result, is.null, logical(1))]

9
2017-07-21 15:49



最后一点可以改进: list.condition <- !vapply(result, is.null, logical(1))。否则一个很好的答案。 - sdgfsdh
@sdgfsdh不错......编辑反映。 - Dean MacGregor
别忘了 ! - sdgfsdh
哎呀,现在就知道了。 - Dean MacGregor
我也会重命名 parsefiles 至 parsefile 因为它一次只能期待一个文件 - 但这很挑剔! - sdgfsdh


正如其他人已经回答的那样,我不认为你可以继续下一次迭代而不使用 *apply 一系列功能。

在这种情况下,我使用Dean MacGregor的方法,只需要做一些小改动:我使用 NA 代替 NULL,这使得过滤结果更容易。

files <- list("file1.txt", "file2.txt", "file3.txt")

parse_file <- function(file) {
  if(file.exists(file)) {
    readLines(file)
  } else {
    NA
  }
}

results <- lapply(files, parse_file)
results <- results[!is.na(results)]

一个快速的基准

res_na   <- list("a",   NA, "c")
res_null <- list("a", NULL, "c")
microbenchmark::microbenchmark(
  na = res_na[!is.na(res_na)],
  null = res_null[!vapply(res_null, is.null, logical(1))]
)

说明了 NA 解决方案比使用的解决方案快得多 NULL

Unit: nanoseconds
expr  min   lq    mean median   uq   max neval
  na    0    1  410.78    446  447  5355   100
null 3123 3570 5283.72   3570 4017 75861   100

2
2018-05-09 07:43





您可以定义要在呼叫中使用的自定义功能 lapply()。下面是一些示例代码,它迭代文件列表并仅在名称不包含数字3时处理文件(有点人为,但希望这可以解决问题):

files <- as.list(c("file1.txt", "file2.txt", "file3.txt"))

fun <- function(x) {
    test <- grep("3", x)                     // check for files with "3" in their name
    if (length(test) == 0) {                 // replace with your statement here
        // process the file here
    }
    // otherwise do not process the file
}

result <- lapply(files, function(x) fun(x))  // call lapply with custom function

0
2017-07-21 15:40