gpt4 book ai didi

r - 定义 `(<-` 运算符时获取 x 的名称

转载 作者:行者123 更新时间:2023-12-04 18:19:52 25 4
gpt4 key购买 nike

我想定义 (<-并访问左侧参数的名称:
*<-函数在内部使用中间体 '*tmp*'多变的。是否仍然可以获得 x 的名称?

`(<-` <- function(x,value){
print(deparse(substitute(value)))
print(deparse(substitute(x)))
print(match.call())
value
}

foo <- 0
(foo) <- 3
# [1] "3"
# [1] "*tmp*"
# `(<-`(x = `*tmp*`, value = 3)# [1] "3"

我想从函数内部获取“foo”。

我试图通过使用 tracemem 来破解它,即调用 sapply(ls(envir = parent.frame()),tracemem)tracemem(x)在函数内部,但地址是 foo , *temp*x都是不同的。

最佳答案

我破解了它,虽然我不明白我所做的一切。

我注意到 pryr::address给出了与 tracemem 不同的结果并尝试了它(我不得不深入研究代码才能使用 pryr:::address2 因为 pryr::address 没有环境参数)。

然后我注意到混合来自 tracemem 的结果在 xpryr:::address2在其余对象上有匹配(在基本重新格式化后):

`(<-` <- function(x,value){
pf <- parent.frame()
all_addresses <- sapply(ls(pf), pryr:::address2, pf)
all_addresses <- all_addresses[names(all_addresses) != "*tmp*"]
all_addresses_short <- gsub("(^|<)[0x]*(.*?)(>|$)","\\2",all_addresses)

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

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

message("all_addresses, using pryr::address2")
print(all_addresses)
print(all_addresses_short)

message("x_address, using tracemem")
print(x_address)
print(x_address_short)

message("x_name, matching substrings")
print(x_name)

value
}
gsub 中使用的正则表达式call 试图解释我们在不同系统中获得的地址格式,我不能 100% 确定它是通用的。

输出:
foo <- 1
bar <- 2
(foo) <- foo

# all_addresses, using pryr::address2
# (<- bar foo
# "0x1433df50" "0x14937678" "0x14937708"
# (<- bar foo
# "1433df50" "14937678" "14937708"
# x_address, using tracemem
# [1] "<0000000014937708>"
# [1] "14937708"
# x_name, matching substrings
# [1] "foo"

如果 x 不是变量名,它就会中断,例如:
foo <- iris
(foo$species) <- 3

我们可以假设如果找不到地址,x 是一个列表项,然后在我们在 parent.frame 中拥有的所有列表的项的地址中查找它的地址。 (递归),但我认为这对于今天来说已经足够丑陋了。

关于r - 定义 `(<-` 运算符时获取 x 的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51246432/

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