【问题标题】:R: lapply function - skipping the current function loopR: lapply 函数 - 跳过当前函数循环
【发布时间】:2015-10-11 03:47:54
【问题描述】:

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

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

【问题讨论】:

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

标签: r function lapply


【解决方案1】:

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

例如如果你有函数parsefile

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

编辑: { 正如 Florent Angly 所示,您应该将 NULL 替换为 NA}

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

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

然后你的列表中就会填满答案和NULLs

您可以通过以下方式对NULLs 进行子集化...

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

【讨论】:

  • 最后一点可以改进:list.condition &lt;- !vapply(result, is.null, logical(1))。否则一个很好的答案。
  • 我还会将 parsefiles 重命名为 parsefile,因为它一次只需要一个文件 - 但这太挑剔了!
  • @sdgfsdh 只为你我做到了
  • result
【解决方案2】:

正如其他人已经回答的那样,我认为如果不使用 *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

【讨论】:

    【解决方案3】:

    您可以定义一个自定义函数以在您对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
    

    【讨论】:

      猜你喜欢
      • 2015-10-12
      • 2021-02-16
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      • 2020-09-20
      • 2011-01-31
      相关资源
      最近更新 更多