模拟R中的动态作用域以通过任意函数进行过滤

问题描述 投票:0回答:1

我在目录中有许多文件,我想根据它们的内容是否满足特定条件在两个新创建的子目录之间分发它们。而且,我需要在多个目录上执行此操作,并且每次条件可能都不同。

我以为我会这样做的方法是创建一个高阶函数,该函数读取文件,从每个文件中提取感兴趣的属性,然后应用条件(作为函数形式的参数提供)从元素的角度到值的向量:

filter.by.property <- function(where, funct) {
  setwd(where)
  paths <- list.files(".", pattern = ".file")
  Robjects <- Map(read.file, paths)
  values <- sapply(Robjects, function(x) property_of_interest(x))
  passes <- Filter(funct, paths)
  dir.create("dir1")
  dir.create("dir2")
  file.copy(passes, paste("./dir1/", 1:length(passes), ".file", sep = ""))
  file.copy(paths[!paths %in% passes], paste("./dir2/", (length(passes) + 1):length(paths), ".file", sep = ""))
}

问题在于,我希望条件指定函数(在funct参数中提供)可以访问values向量。例如:

ten.biggest <- function(path) {
  Robject <- read.file(path)
  property_of_interest(x) %in% tail(sort(values), 10)
}

filter.by.property(<place>, ten.biggest)

由于R在词法范围上,它将在定义了values的环境(全局环境)中而不是在调用它的环境(即ten.biggest内部)中寻找filter.by.property。我可以通过在values中使用filter.by.property的全局赋值来解决此问题,但是除非绝对必要,否则我不愿这样做。我也可以将values作为ten.biggest的另一个参数提供,但是该函数将不再是一元的,而且我不确定Filter内如何仍可以使用该函数。

我尝试的一种解决方案是按如下方式重写ten.biggest

ten.biggest <- function(path) {
  Robject <- read.file(path)
  property_of_interest(x) %in% tail(sort(eval.parent(parse(text = values))), 10)
}

但是那没用。

有什么方法可以在R中模拟动态作用域以使其起作用?通过阅读有关StackExchange的相关问题,似乎body函数可能会有所帮助,但我不知道如何将其应用于我的问题。

我在目录中有许多文件,我想根据它们的内容是否满足特定条件在两个新创建的子目录之间分发它们。而且,我需要...

r higher-order-functions scoping
1个回答
0
投票

我找到了不依赖于交换环境的解决方案。我允许ten.biggest接受两个参数,并在outer_fxn内部定义了一个辅助函数filter.by.property,通过设置其参数之一将二进制函数转换为一元函数。然后可以通过二进制ten.biggest函数通过后者的filter.by.property参数传递给functvalsten.biggest参数由values设置为outer_fxn,然后可以将得到的一元函数设置为在Filter内部使用:

© www.soinside.com 2019 - 2024. All rights reserved.