Я хотел бы вернуть матрицу/data.frame каждую строку, содержащую аргументы и содержимое файла.R - хранить функции в 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);
}
фон
GNU Parallel имеет --results вариант, который хранит выход в структурированном виде. Если есть 1000000 выходных файлов, их может быть сложно управлять. R хорош для этого, но было бы очень медленно, если бы вам нужно было прочитать все 1000000 файлов, чтобы получить те, где аргумент 1 = «Foo» и аргумент 2 = «Bar».
Вы можете иметь функции в матрице, например, 'Foo <- матрица (список (средний С.Д.,' + ', список), 2,2). Но я не думаю, что вам это понадобится, если не считать особого случая. Почему вы не можете хранить имена файлов в матрице или фрейме данных и использовать их при необходимости? – lebatsnok
1e6 файлов - это много файлов, что делает много дорогостоящих 'stat()' вызовов и т. Д. Возможно, посредничество в очереди проще? Мне повезло с redis и R доступом через пакет rredis. –