gpt4 book ai didi

r - 如何在函数内访问分配给函数结果的变量名?

转载 作者:行者123 更新时间:2023-12-04 09:34:22 24 4
gpt4 key购买 nike

例如,假设我希望能够定义一个函数,该函数返回与第一个参数串联的赋值变量的名称:

a <- add_str("b")
a
# "ab"

上面示例中的函数如下所示:
add_str <- function(x) {
arg0 <- as.list(match.call())[[1]]
return(paste0(arg0, x))
}

但是函数的arg0行被替换为一行的行,该行将获取要分配的变量的名称(“a”),而不是函数的名称。

我已经尝试过将match.call和sys.call弄混了,但是我无法使它正常工作。这里的想法是在变量和函数结果上调用赋值运算符,因此它应该是函数调用的父调用。

最佳答案

我认为这并不是严格可行的,正如其他解决方案所解释的那样,合理的选择可能是Yosi的答案。

但是,我们可以从一些想法中获得乐趣,从简单开始,逐渐变得疯狂。

1-定义一个类似于的中缀运算符

`%<-add_str%` <- function(e1, e2) {
e2_ <- e2
e1_ <- as.character(substitute(e1))
eval.parent(substitute(e1 <- paste0(e1_,e2_)))
}

a %<-add_str% "b"
a
# "ab"

2-重新定义:=,以便通过..lhs()函数将lhs的名称提供给rhs

我认为这是我最喜欢的选择:
`:=` <- function(lhs,rhs){
lhs_name <- as.character(substitute(lhs))
assign(lhs_name,eval(substitute(rhs)), envir = parent.frame())
lhs
}

..lhs <- function(){
eval.parent(quote(lhs_name),2)
}

add_str <- function(x){
res <- paste0(..lhs(),x)
res
}

a := add_str("b")
a
# [1] "ab"

可能有一种基于此方法重新定义 <-的方法,但是由于递归问题,我无法弄清楚。

3-使用内存地址暗黑魔法来搜寻lhs(如果存在)

这直接来自: Get name of x when defining `(<-` operator

为此,我们需要更改语法并定义函数 fetch_name,该函数可以从 *<-函数获取rhs的名称,其中 as.character(substitute(lhs))将返回 "*tmp*"
fetch_name <- function(x,env = parent.frame(2)) {
all_addresses <- sapply(ls(env), pryr:::address2, env)
all_addresses <- all_addresses[names(all_addresses) != "*tmp*"]
all_addresses_short <- gsub("(^|<)[0x]*(.*?)(>|$)","\\2",all_addresses)

x_address <- tracemem(x)
untracemem(x)
x_address_short <- tolower(gsub("(^|<)[0x]*(.*?)(>|$)","\\2",x_address))

ind <- match(x_address_short, all_addresses_short)
x_name <- names(all_addresses)[ind]
x_name
}

`add_str<-` <- function(x,value){
x_name <- fetch_name(x)
paste0(x_name,value)
}

a <- NA
add_str(a) <- "b"
a

4-后者的一种变体,使用.Last.value:
add_str <- function(value){
x_name <- fetch_name(.Last.value)
assign(x_name,paste0(x_name,value),envir = parent.frame())
paste0(x_name,value)
}

a <- NA;add_str("b")
a
# [1] "ab"

操作不必排在同一行,但它们需要彼此跟随。

5-还是一种变体,使用打印方法hack

极其肮脏和令人费解的,请取悦被折磨的精神,并诱骗其他人。

这是唯一真正提供预期输出的设备,但仅在交互模式下有效。

诀窍在于,除了执行第一个操作中的所有工作之外,我还使用第二个(打印)操作。因此,在第一步中,我返回一个值为 "b"的对象,但我还为它分配了一个 "weird"类和一个打印方法,然后该打印方法修改该对象的值,重置其类并破坏自身。
add_str <- function(x){
class(x) <- "weird"
assign("print.weird", function(x) {
env <- parent.frame(2)
x_name <- fetch_name(x, env)
assign(x_name,paste0(x_name,unclass(x)),envir = env)
rm(print.weird,envir = env)
print(paste0(x_name,x))
},envir = parent.frame())
x
}

a <- add_str("b")
a
# [1] "ab"
(a <- add_str("b")将具有与以上两行相同的效果。 print(a <- add_str("b"))也将具有相同的效果,但也将在非交互式代码中工作。

关于r - 如何在函数内访问分配给函数结果的变量名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46204937/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com