携带多个函数的R对象名称
R object's name carrying through multiple functions
根据我对 Hadley's advice on building S3 objects 的阅读,我正在使用辅助函数、构造函数和验证器函数。一个简单的可重现示例:
test_object <- function(x, y, z) {
new_test_object(x, y, z)
}
new_test_object <- function(x, y, z) {
structure(list(x = x,
y = y,
z = z,
x_name = deparse(substitute(x))),
class = "test_object")
}
validate_test_object <- function(test_object) {
# Anything goes
test_object
}
我希望生成的对象包含一个值,该值具有传入的项目的原始名称(上例中的$x_name
)。如果我直接调用构造函数,deparse(substitute(...))
技巧就会起作用:
alpha = "a"
test_constructor <- new_test_object(x = alpha, y = "b", z = "c")
test_constructor$x_name
# [1] "alpha"
但如果我使用辅助函数则不会:
test_helper <- test_object(x = alpha, y = "b", z = "c")
test_helper$x_name
# [1] "x"
我想 test_helper$x_name
也 return [1] "alpha"
.
如果不在辅助阶段执行 deparse(substitute(...))
步骤,构造函数 (new_test_object()
) 是否有任何方法可以访问对象的 'original' 名称 x
如果它是通过助手来的?或者确保它的名称在辅助函数将其传递给构造函数时随它一起传递?
这里有一个不完美的修复:当你从另一个函数调用它时,你添加 ...
参数来传递名称
test_object <- function(x, y, z) {
x_name = deparse(substitute(x))
new_test_object(x, y, z, x_name = x_name)
}
new_test_object <- function(x, y, z, ...) {
args <- list(...)
if(is.null(args[["x_name"]])){
structure(list(x = x,
y = y,
z = z,
x_name = deparse(substitute(x))),
class = "test_object")
}
else{
structure(list(x = x,
y = y,
z = z,
x_name = args[["x_name"]]),
class = "test_object")
}
}
结果如下:
test_helper <- test_object(x = alpha, y = "b", z = "c")
test_helper$x_name
# [1] "alpha"
这里的真正目的是什么?如果您只是将一个函数用作另一个函数的包装器,那么有更好的方法来保留参数。例如
test_object <- function(x, y, z) {
call <- match.call()
call[[1]] <- quote(new_test_object)
eval(call)
}
但总的来说,依靠deparse()
从变量名中获取信息并不是一个非常可靠的方法。如果这些信息是您可以根据需要设置的适当参数,那就更好了。这使您的功能更加灵活。
test_object <- function(x, y, z, xname=deparse(substitute(x))) {
new_test_object(x, y, z, xname=xname)
}
new_test_object <- function(x, y, z, xname=deparse(substitute(x))) {
structure(list(x = x,
y = y,
z = z,
x_name = xname),
class = "test_object")
}
根据我对 Hadley's advice on building S3 objects 的阅读,我正在使用辅助函数、构造函数和验证器函数。一个简单的可重现示例:
test_object <- function(x, y, z) {
new_test_object(x, y, z)
}
new_test_object <- function(x, y, z) {
structure(list(x = x,
y = y,
z = z,
x_name = deparse(substitute(x))),
class = "test_object")
}
validate_test_object <- function(test_object) {
# Anything goes
test_object
}
我希望生成的对象包含一个值,该值具有传入的项目的原始名称(上例中的$x_name
)。如果我直接调用构造函数,deparse(substitute(...))
技巧就会起作用:
alpha = "a"
test_constructor <- new_test_object(x = alpha, y = "b", z = "c")
test_constructor$x_name
# [1] "alpha"
但如果我使用辅助函数则不会:
test_helper <- test_object(x = alpha, y = "b", z = "c")
test_helper$x_name
# [1] "x"
我想 test_helper$x_name
也 return [1] "alpha"
.
如果不在辅助阶段执行 deparse(substitute(...))
步骤,构造函数 (new_test_object()
) 是否有任何方法可以访问对象的 'original' 名称 x
如果它是通过助手来的?或者确保它的名称在辅助函数将其传递给构造函数时随它一起传递?
这里有一个不完美的修复:当你从另一个函数调用它时,你添加 ...
参数来传递名称
test_object <- function(x, y, z) {
x_name = deparse(substitute(x))
new_test_object(x, y, z, x_name = x_name)
}
new_test_object <- function(x, y, z, ...) {
args <- list(...)
if(is.null(args[["x_name"]])){
structure(list(x = x,
y = y,
z = z,
x_name = deparse(substitute(x))),
class = "test_object")
}
else{
structure(list(x = x,
y = y,
z = z,
x_name = args[["x_name"]]),
class = "test_object")
}
}
结果如下:
test_helper <- test_object(x = alpha, y = "b", z = "c")
test_helper$x_name
# [1] "alpha"
这里的真正目的是什么?如果您只是将一个函数用作另一个函数的包装器,那么有更好的方法来保留参数。例如
test_object <- function(x, y, z) {
call <- match.call()
call[[1]] <- quote(new_test_object)
eval(call)
}
但总的来说,依靠deparse()
从变量名中获取信息并不是一个非常可靠的方法。如果这些信息是您可以根据需要设置的适当参数,那就更好了。这使您的功能更加灵活。
test_object <- function(x, y, z, xname=deparse(substitute(x))) {
new_test_object(x, y, z, xname=xname)
}
new_test_object <- function(x, y, z, xname=deparse(substitute(x))) {
structure(list(x = x,
y = y,
z = z,
x_name = xname),
class = "test_object")
}