要临时编辑已打包函数func
的正文,我经常使用trace(func, edit=TRUE)
。出于某种原因,当func
为[.data.table
时,R不允许我这样做:
## Note: In this and the other cases below, once an editor pops up, I save and
## and then exit without making any edits to the function. The commented-out
## message below each call to trace() is what is then printed to my R console.
trace("[.data.table", where=data.table, edit=TRUE)
# Error in .makeTracedFunction(def, tracer, exit, at, print, doEdit) :
# the editing in trace() can only change the body of the function, not
# the arguments or defaults
问题:可能导致此错误的原因是什么?还有哪些其他功能会触发它?对于这样的函数,是否有一些替代解决方法可以让我编辑它们?
FWIW,这似乎不是 data.table 命名空间中的函数的一般问题(参见下面的#1
),也不是子集方法的问题一般(见下文#2
)。
## (#1)
trace("within.data.table", where=data.table, edit=TRUE)
# Tracing function "within.data.table" as seen from package "data.table"
# [1] "within.data.table"
## (#2)
trace("[.Date", edit=TRUE)
# Tracing function "[.Date" in package "base"
# [1] "[.Date"
我在Windows XP计算机上运行R-3.0.0
和data.table_1.8.8
,无论是使用set options(editor="emacs")
,options(editor="notepad")
还是使用R GUI的默认编辑器,都会出现相同的错误
答案 0 :(得分:5)
这显然是由于最近在{}
的正式参数列表中的一个地方添加了花括号(即data.table
)。
首先,MRE显示大括号确实导致trace(..., edit=TRUE)
窒息:
## Without braces, no problem
func <- function(inColor=FALSE, col = if(inColor) "red" else "grey") {
plot(rnorm(99), col=col)}
trace(func, edit=TRUE)
# [1] "func"
## With braces, tracing fails
funcB <- function(inColor=FALSE, col = if(inColor) "red" else {"grey"}) {
plot(rnorm(99), col=col)}
trace(funcB, edit=TRUE)
# Error in .makeTracedFunction(def, tracer, exit, at, print, doEdit) :
# the editing in trace() can only change the body of the function, not
# the arguments or defaults
然后,为了记录,这里是版本1.8.6中[.data.table
的正式(跟踪工作)和版本1.8.8(它不支持):
## Version 1.8.6 -- Tracing worked
function (x, i, j, by, keyby, with=TRUE, nomatch=getOption("datatable.nomatch"),
mult="all", roll=FALSE, rolltolast=FALSE,
which=FALSE, .SDcols, verbose=getOption("datatable.verbose"), drop=NULL)
## Version 1.8.8 -- Tracing doesn't (See {} in the 'rollends' argument)
function (x, i, j, by, keyby, with=TRUE, nomatch=getOption("datatable.nomatch"),
mult = "all", roll = FALSE,
rollends = if (roll == "nearest") c(TRUE,
TRUE) else {
if (roll >= 0)
c(FALSE, TRUE)
else c(TRUE, FALSE)
},
which = FALSE, .SDcols, verbose = getOption("datatable.verbose"),
allow.cartesian = getOption("datatable.allow.cartesian"),
drop = NULL, rolltolast = FALSE)