【问题标题】:Redefining a function in an R package重新定义 R 包中的函数
【发布时间】:2013-04-25 10:11:48
【问题描述】:

我尝试通过首先定义一个函数来修改和重新定义R包xcms中的一个函数(xcmsRaw)

my.xcmsRaw <- function(filename, profstep = 1, profmethod = "bin",
                    profparam = list(mzcorrf=1),    # PATCH - mzcorrf is the m/z correction factor, e.g. 0.99888 for long-chain hydrocarbons
                    includeMSn = FALSE, mslevel=NULL,
                    scanrange=NULL) { ... }

然后输入

unlockBinding("xcmsRaw", as.environment("package:xcms"))
assign("xcmsRaw", my.xcmsRaw, as.environment("package:xcms"))
lockBinding("xcmsRaw", as.environment("package:xcms"))

但是,当我运行它时,它给了我错误

Error in get(as.character(FUN), mode = "function", envir = envir) : 
  object 'profBinM' of mode 'function' was not found

因为没有找到profBinM函数,这是一个定义在xcms包的xcms.c文件中的C代码函数。

对如何解决此问题有任何想法吗? (我在 Windows 7 下工作,使用 R 版本 3.0.0)

【问题讨论】:

  • 您是否尝试过assignInNamespace(),例如this example?在你的情况下,你会使用类似assignInNamespace(x="xcmsRaw", value="my.xcmsRaw", ns=asNamespace("xcms"))
  • 感谢您的建议,刚刚尝试过,但不幸的是它仍然给我同样的错误......
  • 有趣。准确地说/清楚,profBinM() 是一个 R 函数包装了一个 C 函数。
  • 是的,该函数在文件 xcms.c 中定义(在 Windows 中这当然已经被预编译)为 void ProfBinM(double *xvals, double *yvals, int *numin, int *mindex, int *nummi, double *xstart, double *xend, int *numout, double *out) { ... }
  • 您是否尝试过 trace(xcmsRaw, edit=TRUE) 并以这种方式进行更改?

标签: r function package redefine


【解决方案1】:

谢谢 Josh - 就我而言,我现在通过

让它工作了
modifline='if ((profparam$mzcorrf!=1)&length(unique(rawdata$mz - trunc(rawdata$mz)))!=1) {rawdata$mz=rawdata$mz*profparam$mzcorrf} else if (profparam$mzcorrf!=1) {print("Exact masses were already rounded to nominal masses");profparam$mzcorrf=1}'
insertatline=6
trace(xcmsRaw, tracer=modifline,at=c(insertatline))

我找到了正确的行来插入我修改后的代码使用

as.list(body(xcmsRaw))

为了抑制跟踪的输出,我定义了第二个函数

xcmsRaw2=function(...) {sink("NUL");obj=xcmsRaw(...);sink();return(obj) }

可以调用,不提供任何不必要的跟踪输出。

通过 assignInNamespace() 让它工作仍然会很好,因为这将允许更广泛的编辑/重新定义以及函数参数的更改(这将是重新定义函数的常见原因,即采取一些额外的论点)...

【讨论】:

  • 太棒了!我同意,这感觉像是一个黑客,但它的概率。在您找到更灵活/优雅的解决方案之前,总比没有好。
  • 哦,是的,有什么方法可以抑制跟踪的输出吗?现在每次我调用 xcmsRaw 它都会打印“Tracing xcmsRaw(files[samplenr], profstep = profst, profmethod = "bin", .... step 6" - 但我想抑制这个输出。有什么办法可以这样做?
  • 我唯一的想法是将您对xcmsRaw() 的电话转入suppressMessages()。如果可行,您可以编写一个非常薄的包装函数——也许称之为xcmsRaw2——将所有参数传递给suppressMessages(xcmsRaw(...))。但请记住,这仅适用于直接调用xcmsRaw,不适用于包中其他函数的调用。或者,您可以只修改包源并重新编译包含您的新的和改进的xcmsRaw 的版本;)
  • 奇怪的是,如果我定义 xcmsRaw2=function(...) {suppressMessages(xcmsRaw(...))} 我仍然得到 Tracing xcmsRaw(...) step 6 作为输出,所以没有t 似乎工作......所以是的,将不得不重新编译,但这会有点混乱,因为我想将它与我的包一起打包,然后我必须弄清楚我将和不必复制...
  • 哈,但是 xcmsRaw2=function(...) {sink("NUL");obj=xcmsRaw(...);sink();return(obj) } 成功了...谢谢!
猜你喜欢
  • 2020-02-12
  • 2021-05-29
  • 2018-04-16
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-29
相关资源
最近更新 更多