关于优化 R 中的工作流程,我有一个我认为很常见的问题。具体来说,我怎样才能避免文件夹中充满输出(绘图、RData 文件、csv 等)的常见问题,而在一段时间后没有,知道它们来自哪里或它们是如何产生的吗?在某种程度上,它肯定涉及尝试对文件夹结构进行智能处理。我一直在环顾四周,但我不确定最好的策略是什么。到目前为止,我已经以一种相当简单(矫枉过正)的方式解决了它:我创建了一个函数metainfo
(见下文),它使用给定的文件名写入带有元数据的文本文件。想法是,如果生成了绘图,则发出此命令以生成与绘图完全相同的文件名的文本文件(当然,扩展名除外),其中包含有关系统、会话、加载的包、R 的信息调用元数据函数的版本、函数和文件等。问题是:
(i) 人们如何处理这个普遍的问题?有没有明显的方法可以避免我提到的问题?
(ii) 如果没有,是否有人对改进此功能有任何提示?目前它可能很笨重而且不理想。特别是,获取生成绘图的文件名不一定有效(我使用的解决方案是 @hadley 在1中提供的解决方案)。欢迎任何想法!
该函数假定为 git,因此请忽略可能产生的警告。这是主要功能,存储在文件中metainfo.R
:
MetaInfo <- function(message=NULL, filename)
{
# message - character string - Any message to be written into the information
# file (e.g., data used).
# filename - character string - the name of the txt file (including relative
# path). Should be the same as the output file it describes (RData,
# csv, pdf).
#
if (is.null(filename))
{
stop('Provide an output filename - parameter filename.')
}
filename <- paste(filename, '.txt', sep='')
# Try to get as close as possible to getting the file name from which the
# function is called.
source.file <- lapply(sys.frames(), function(x) x$ofile)
source.file <- Filter(Negate(is.null), source.file)
t.sf <- try(source.file <- basename(source.file[[length(source.file)]]),
silent=TRUE)
if (class(t.sf) == 'try-error')
{
source.file <- NULL
}
func <- deparse(sys.call(-1))
# MetaInfo isn't always called from within another function, so func could
# return as NULL or as general environment.
if (any(grepl('eval', func, ignore.case=TRUE)))
{
func <- NULL
}
time <- strftime(Sys.time(), "%Y/%m/%d %H:%M:%S")
git.h <- system('git log --pretty=format:"%h" -n 1', intern=TRUE)
meta <- list(Message=message,
Source=paste(source.file, ' on ', time, sep=''),
Functions=func,
System=Sys.info(),
Session=sessionInfo(),
Git.hash=git.h)
sink(file=filename)
print(meta)
sink(file=NULL)
}
然后可以在另一个函数中调用它,存储在另一个文件中,例如:
source('metainfo.R')
RandomPlot <- function(x, y)
{
fn <- 'random_plot'
pdf(file=paste(fn, '.pdf', sep=''))
plot(x, y)
MetaInfo(message=NULL, filename=fn)
dev.off()
}
x <- 1:10
y <- runif(10)
RandomPlot(x, y)
这样,将生成一个与绘图具有相同文件名的文本文件,其中的信息有望帮助确定绘图的生成方式和位置。