调用函数时如何获取R脚本文件名? [英] How to get R script file name when a function in it is called?

查看:107
本文介绍了调用函数时如何获取R脚本文件名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个R脚本文件,例如 f1.R f2.R f3.R .

I have several R script files, such as f1.R, f2.R, f3.R.

我还有一个名为AddSignal(signal)的函数,该函数将信号向量添加到列表中.f1.R,f2.R等中的函数可以调用此AddSignal()函数.

I have another function called AddSignal(signal), which adds a signal vector to a list. Functions in f1.R, f2.R, etc. may call this AddSignal() function.

现在我想要的是,在函数AddSignal()中,除了执行添加信号部分外,它还记录了哪个函数在哪个R文件中进行了调用.例如,我想知道f1.R添加信号sig1中的函数ff1().

Now what I want is that, in function AddSignal(), besides doing the add signal part, it also records which function in which R file made the call. For example, I'd like to know function ff1() in f1.R added signal sig1.

有办法吗?

实际上,使用sys.call(),我可以知道哪个函数(例如ff1())称为AddSignal().但是我不知道ff1()位于哪个R文件中.我可以看到一个困难的方法,即扫描所有.R文件,然后存储文件名和函数名的映射.但我想看看是否有更简单的方法.

In fact, using sys.call(), I can know which function (for example, ff1()) called AddSignal(). But I don't know which R file that ff1() is in. I can see a hard way of doing it, is to scan all .R files and then store a mapping of file names and function names. But I'd like to see whether there is an easier way of doing it.

谢谢.

推荐答案

我要做的是创建一个查找表,该表将函数映射到其所在的 .R 文件.您必须重新创建每次添加,删除或移动函数时都使用此表,但是我认为最好是每次要查找函数的源文件时都重新生成表.所以这是我对创建这样一个表的看法:

What I would do is create a lookup table which maps a function to the .R file it is in. You have to recreate this table every time you add, remove, or move a function, but I think it would be preferable to regenerating the table every time you want to find the source file of a function. So here is my take on create such a table:

library(plyr)

functionsFromRfile = function(filename) {
# Get all functions from a source file. Create new enviroment
# source the functions into them and use ls() to extract names.
  e = new.env()
  source(filename, local = e)
  return(ls(envir = e))
}

# This assumes you are in the directory with your R code,
# and that all files need to be included. You can also
# make this list manually ofcourse
Rfiles = list.files(".", pattern = ".R")
# Get a list of functions for each .R file
lutFunc2sourcefile = ldply(Rfiles, function(x) {
  return(data.frame(fname = x, func = functionsFromRfile(x)))
})

对于我自己的软件包之一,它导致:

For one of my own packages this leads to:

> head(lutFunc2sourcefile)
               fname                func
1 autofitVariogram.r    autofitVariogram
2     autoKrige.cv.r        autoKrige.cv
3     autoKrige.cv.r checkIfautokrige.cv
4     autoKrige.cv.r          compare.cv
5     autoKrige.cv.r   cv.compare.bubble
6     autoKrige.cv.r   cv.compare.ggplot

您可以使用查找表来执行从 sys.call 获得的函数名称的映射.

You can use the lookup table to performing the mapping using the function name obtained from sys.call.

编辑:鉴于您对非功能代码的评论,该代码使用了分析功能,该功能不会评估该代码.它搜索语法分析的输出,并淘汰函数,并且不应评估不是函数的任何代码或返回代码.我尚未对其进行详尽的测试,请尝试一下.

EDIT: In view of your comment on non-function code, this code uses parse, which does not evaluate the code. It searches through the output of parse, and weeds out the functions, and should not evaluate any code or return code that is not a function. I haven't tested it exhaustively, give it a try.

library(plyr)

Rfiles = list.files(".", pattern = "(.R|.r)")
lutFunc2sourcefile = ldply(Rfiles, function(fname) {
   f = parse(fname)
   functions = sapply(strsplit(as.character(f), "="), function(l) {
     if(grepl("^function", sub(' ', '', l[2]))) {
       return(l[1])
     } else {
       return(NA)
     }
    })
   return(data.frame(fname, func = functions))  
})
# Remove lines with func = NA
lutFunc2sourcefile = lutFunc2sourcefile[!is.na(lutFunc2sourcefile$func),]

这篇关于调用函数时如何获取R脚本文件名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆