Ole*_*nge 5 r function lazy-evaluation
我想返回一个 matrix/data.frame 每行包含参数和文件的内容。
但是,可能有很多文件,所以我更愿意延迟加载文件,因此只有在请求实际内容时才会读取文件。下面的函数主动加载文件,如果as.func=F.
如果它可以延迟加载它们将是完美的,但如果不是内容而是返回一个可以读取内容的函数,这也是可以接受的。
我可以制作读取内容的函数(见下文as.func=T),但由于某种原因,我无法将其放入 data.frame 中以返回。
load_parallel_results <- function(resdir,as.func=F) {
## Find files called .../stdout
stdoutnames <- list.files(path=resdir, pattern="stdout", recursive=T);
## Find files called .../stderr
stderrnames <- list.files(path=resdir, pattern="stderr", recursive=T);
if(as.func) {
## Create functions to read them
stdoutcontents <-
lapply(stdoutnames, function(x) { force(x); return(function() { return(paste(readLines(paste(resdir,x,sep="/")),collapse="\n")) } ) } );
stderrcontents <-
lapply(stderrnames, function(x) { force(x); return(function() { return(paste(readLines(paste(resdir,x,sep="/")),collapse="\n")) } ) } );
} else {
## Read them
stdoutcontents <-
lapply(stdoutnames, function(x) { return(paste(readLines(paste(resdir,x,sep="/")),collapse="\n")) } );
stderrcontents <-
lapply(stderrnames, function(x) { return(paste(readLines(paste(resdir,x,sep="/")),collapse="\n")) } );
}
if(length(stdoutnames) == 0) {
## Return empty data frame if no files found
return(data.frame());
}
## Make the columns containing the variable values
m <- matrix(unlist(strsplit(stdoutnames, "/")),nrow = length(stdoutnames),byrow=T);
mm <- as.data.frame(m[,c(F,T)]);
## Append the stdout and stderr column
mmm <- cbind(mm,unlist(stdoutcontents),unlist(stderrcontents));
colnames(mmm) <- c(strsplit(stdoutnames[1],"/")[[1]][c(T,F)],"stderr");
## Example:
## parallel --results my/res/dir --header : 'echo {};seq {myvar1}' ::: myvar1 1 2 ::: myvar2 A B
## > load_parallel_results("my/res/dir")
## myvar1 myvar2 stdout stderr
## [1,] "1" "A" "1 A\n1" ""
## [2,] "1" "B" "1 B\n1" ""
## [3,] "2" "A" "2 A\n1\n2" ""
## [4,] "2" "B" "2 B\n1\n2" ""
return(mmm);
}
Run Code Online (Sandbox Code Playgroud)
背景
GNU Parallel 有一个 --results 选项,它以结构化的方式存储输出。如果有 1000000 个输出文件,可能很难管理它们。R 对此有好处,但是如果您必须读取所有 1000000 个文件来获取参数 1 = "Foo" 和参数 2 = "Bar" 的文件,那将会非常慢。
不幸的是,我认为您不能在 data.frame 列中保存函数。但是您可以存储函数的解析文本并在需要时对其进行评估:
例如
myFunc <- function(x) { print(x) }
# convert the function to text
funcAsText <- deparse(myFunc)
# convert the text back to a function
newMyFunc <- eval(parse(text=funcAsText))
# now you can use the function newMyFunc exactly like myFunc
newMyFunc("foo")
> [1] "foo"
Run Code Online (Sandbox Code Playgroud)
编辑:
由于文件很多,我建议您简单地存储一个指示文件类型的字符串,并创建一个理解类型并相应地读取文件的函数;因此您可以在需要时通过传递类型和文件路径来调用它。