R: on.exit - 在不知道名称的情况下使用返回值
R: on.exit - use returned value without knowing its name
我有以下功能。除了函数中的第一段代码之外,我无法以任何方式更改函数。
在这个简单的例子中,我想显示在返回对象上应用一些函数。
关键是函数返回的变量名称可能会有所不同,我猜不出来。
显然我也不能将 f
函数包装到 { x <- f(); myfun(x); x }
.
我的 on.exit
调用中下面的 .Last.value
表示 f
函数要返回的值。
f <- function(param){
# the only code I know - start
on.exit(if("character" %in% class(.Last.value)) message(print(.Last.value)) else message(class(.Last.value)))
# the only code I know - end
# real processing of f()
a <- "aaa"
"somethiiiing"
if(param==1L) return(a)
b <- 5L
"somethiiiing"
if(param==2L) return(b)
"somethiiiing"
return(32)
}
f(1L)
# function
# [1] "aaa"
f(2L)
# aaa
# [1] 5
f(3L)
# integer
# [1] 32
上面带有 .Last.value
的代码似乎在 与滞后 一起工作(所以实际上不工作)而且 .Last.value
可能不是go 因为我想像 if(fun0(x)) fun1(x) else fun2(x)
那样多次使用该值,并且因为返回值可能是一个大对象,所以将它复制到一边也是不好的方法。
在不知道结果变量名称的情况下,使用 on.exit
或任何其他函数可以帮助我 运行 我在 f
函数结果上的函数的任何方法?
与您修改函数的方式类似,您也可以轻松地包装它。这是一个可重现的例子。
library(data.table)
append.log<-function(x) {
cat(paste("value:",x,"\n"))
}
idx.dt <- data.table:::`[.data.table`
environment(idx.dt)<-asNamespace("data.table")
idx.wrap <- function(...) {
x<-do.call(idx.dt, as.list(substitute(...())), envir=parent.frame())
append.log(if(is(x, "data.table")) {
nrow(x)
} else { NA })
x
}
environment(idx.wrap)<-asNamespace("data.table")
(unlockBinding)("[.data.table",asNamespace("data.table"))
assign("[.data.table",idx.wrap,envir=asNamespace("data.table"),inherits=FALSE)
dt<-data.table(a=1:10, b=seq(2, 20, by=2), c=letters[1:10])
dt[a%%2==0]
从 R 3.2.0 开始完全有可能,这要归功于新功能 returnValue
。
下面的工作示例。
f <- function(x, err = FALSE){
pt <- proc.time()[[3L]]
on.exit(message(paste("proc.time:",round(proc.time()[[3L]]-pt,4),"\nnrow:",as.integer(nrow(returnValue()))[1L])))
Sys.sleep(0.001)
if(err) stop("some error")
return(x)
}
dt <- data.frame(a = 1:5, b = letters[1:5])
f(dt)
f(dt, err=T)
f(dt)
f(dt[dt$a %in% 2:3 & dt$b %in% c("c","d"),])
我有以下功能。除了函数中的第一段代码之外,我无法以任何方式更改函数。
在这个简单的例子中,我想显示在返回对象上应用一些函数。
关键是函数返回的变量名称可能会有所不同,我猜不出来。
显然我也不能将 f
函数包装到 { x <- f(); myfun(x); x }
.
我的 on.exit
调用中下面的 .Last.value
表示 f
函数要返回的值。
f <- function(param){
# the only code I know - start
on.exit(if("character" %in% class(.Last.value)) message(print(.Last.value)) else message(class(.Last.value)))
# the only code I know - end
# real processing of f()
a <- "aaa"
"somethiiiing"
if(param==1L) return(a)
b <- 5L
"somethiiiing"
if(param==2L) return(b)
"somethiiiing"
return(32)
}
f(1L)
# function
# [1] "aaa"
f(2L)
# aaa
# [1] 5
f(3L)
# integer
# [1] 32
上面带有 .Last.value
的代码似乎在 与滞后 一起工作(所以实际上不工作)而且 .Last.value
可能不是go 因为我想像 if(fun0(x)) fun1(x) else fun2(x)
那样多次使用该值,并且因为返回值可能是一个大对象,所以将它复制到一边也是不好的方法。
在不知道结果变量名称的情况下,使用 on.exit
或任何其他函数可以帮助我 运行 我在 f
函数结果上的函数的任何方法?
与您修改函数的方式类似,您也可以轻松地包装它。这是一个可重现的例子。
library(data.table)
append.log<-function(x) {
cat(paste("value:",x,"\n"))
}
idx.dt <- data.table:::`[.data.table`
environment(idx.dt)<-asNamespace("data.table")
idx.wrap <- function(...) {
x<-do.call(idx.dt, as.list(substitute(...())), envir=parent.frame())
append.log(if(is(x, "data.table")) {
nrow(x)
} else { NA })
x
}
environment(idx.wrap)<-asNamespace("data.table")
(unlockBinding)("[.data.table",asNamespace("data.table"))
assign("[.data.table",idx.wrap,envir=asNamespace("data.table"),inherits=FALSE)
dt<-data.table(a=1:10, b=seq(2, 20, by=2), c=letters[1:10])
dt[a%%2==0]
从 R 3.2.0 开始完全有可能,这要归功于新功能 returnValue
。
下面的工作示例。
f <- function(x, err = FALSE){
pt <- proc.time()[[3L]]
on.exit(message(paste("proc.time:",round(proc.time()[[3L]]-pt,4),"\nnrow:",as.integer(nrow(returnValue()))[1L])))
Sys.sleep(0.001)
if(err) stop("some error")
return(x)
}
dt <- data.frame(a = 1:5, b = letters[1:5])
f(dt)
f(dt, err=T)
f(dt)
f(dt[dt$a %in% 2:3 & dt$b %in% c("c","d"),])