【问题标题】:How can I create a custom assignment using a replacement function?如何使用替换功能创建自定义分配?
【发布时间】:2011-09-22 05:27:26
【问题描述】:

我定义了一个名为once的函数,如下:

once <- function(x, value) {
    xname <- deparse(substitute(x))
    if(!exists(xname)) {
        assign(xname, value, env=parent.frame())
    }
    invisible()
}

想法是 value 的评估很耗时,我只想在第一次运行脚本时将其分配给 x

> z
Error: object 'z' not found
> once(z, 3)
> z
[1] 3

我真的很希望使用 once(x) &lt;- value 而不是 once(x, value),但是如果我编写一个函数 once&lt;-,它会因为变量不存在而感到不安:

> once(z) <- 3
Error in once(z) <- 3 : object 'z' not found

有人有办法解决这个问题吗?

ps:有没有像once&lt;- 或一般的f&lt;- 这样描述函数的名称?

【问题讨论】:

  • 它们被称为替换函数
  • @Andrie:有关于 SO 的编码风格指南吗?我个人偏爱更多的空白,但如果这里有编码标准,我可以通过在将来遵循它们来节省编辑时间。
  • @pete 网页上太多的空白意味着问题不再适合单个屏幕并且变得非常难以阅读。那是官方的SO指南吗?可能不是。如果您不喜欢它,请随时恢复为原始版本。

标签: r


【解决方案1】:

如果您愿意稍微修改您的要求以使用方括号而不是圆括号,那么您可以这样做:

once <- structure(NA, class = "once")
"[<-.once" <- function(once, x, value) {
    xname <- deparse(substitute(x))
    pf <- parent.frame()
    if (!exists(xname, pf)) assign(xname, value, pf)
    once
}


# assigns 3 to x (assuming x does not currently exist)
once[x] <- 3
x # 3

# skips assignment (since x now exists)
once[x] <- 4
x # 3

【讨论】:

  • 哇,既美丽又可怕。喜欢它。
  • 酷!我使用这种方法创建了一个多返回运算符,类似于 python。
【解决方案2】:

根据 R 语言参考中的 3.4.4 项,类似名称替换的评估如下:

 `*tmp*` <- x
 x <- "names<-"(`*tmp*`, value=c("a","b"))
 rm(`*tmp*`)

这对您的要求来说是个坏消息,因为分配将在第一行失败(因为 x 未找到),即使它可以工作,您的 deparse(substitute) 调用也永远不会评估您想要的结果。

很抱歉让你失望了

【讨论】:

  • 了解一种或另一种方式是件好事。现在我可以重命名我的函数assign_once 并停止拖延。此外,RLR 将 f&lt;- 称为“复杂分配”,如果我以后需要搜索它,这将对我有所帮助。
  • 嗯,这是我最喜欢的 RLR 部分。每当我被窃听时,事实证明这部分与它有关。
猜你喜欢
  • 2014-04-25
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 2013-01-15
  • 2014-02-01
  • 1970-01-01
相关资源
最近更新 更多