R 中的惰性求值 – 赋值会受到影响吗? [英] Lazy evaluation in R – is assign affected?

查看:33
本文介绍了R 中的惰性求值 – 赋值会受到影响吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了关于重命名对象和@Shane 的这个基本问题's answer to it,指向我懒惰的评估.现在我想知道 assign 是否也被懒惰地评估了.就像这里:

I read this basic question on renaming objects and @Shane 's answer to it, pointing me to lazy evaluation. Now I wonder if assign is evaluated lazily, too. Just like here:

assign("someNewName",someOldObject)
rm(someOldObject)

我对此感到疑惑的原因是以下用例:假设我有 10K+ R 个对象,每个对象都有两个属性,称为 originalNameadditionalName.现在我想编写一个函数,可以有效地让用户从一个名称切换到另一个名称,而不会丢失这两个属性.大致是这样的...

The reason why I wonder about this is the following use case: Assume I got 10K+ R objects each of which has two attributes called originalName and additionalName. Now I want to write a function that can efficiently let the user switch from one name to the other without losing these two attributes. Roughly like this...

根据@Hadley 的输入,我更改了代码.

based on @Hadley's input I have changed my code.

switchObjectName <- function(x) {
  n1 <- attributes(x)$originalName
  n2 <- attributes(x)$additionalName
  objName <- deparse(substitute(x))
  if(objName == n1) {
    delayedAssign(n2,x,assign.env=.GlobalEnv)
  } else {
    delayedAssign(n1,x,assign.env=.GlobalEnv)
  }
  rm(list=c(objName),envir=.GlobalEnv)    
}

这很有效,但我在正确使用 rm 语句时遇到了一些麻烦.我尝试了 rm(objName,envir=.GlobalEnv) 但无法让它工作,尽管 objName 绝对是一个字符,因为它是 deparse(substitute(x) 的结果.

this works well, but I had quite some trouble to get the rm statement right. I tried rm(objName,envir=.GlobalEnv) but could not get it to work though objName is definitely a character cause it is the result of deparse(substitute(x).

推荐答案

R 语言通常具有值语义.赋值 x <- y 意味着 xy 将是同一对象的独立副本(更新 ycode> 和 x 将是独立的).x <- y 的简单实现总是会为 x 分配内存并将 y 完全复制到其中.GNU-R 改为使用写时复制机制,它会将复制推迟到实际发生更新之前,这样可以节省内存/执行时间,以防万一它没有发生.R 用户不必知道这种优化,它是完全透明的(除了一些罕见的情况,如内存不足错误).这种机制同样适用于写为 x <- yassign("x", y) 的赋值.

The R language generally has value semantics. The assignment x <- y means that x and y will be independent copies of the same object (updates on y and x will be independent). A naive implementation of x <- y would always allocate memory for x and fully copy y into it. GNU-R instead uses a copy-on-write mechanism, it would postpone the copy until an update actually happens, which saves memory/execution time in case it does not happen. R users do not have to know about this optimization, it is fully transparent (except some rare cases like out-of-memory errors). This mechanism applies to assignment written as x <- y and assign("x", y) equally.

惰性求值是语言设计的一部分,对 R 用户/程序员可见.作为参数传递给函数的表达式,例如在 foo(ls()) 中,传递的表达式是 ls(),仅在被调用函数的实现需要时才进行延迟计算.

Lazy evaluation is part of the design of the language and is visible to R users/programmers. Expressions passed as arguments to a function, e.g. in foo(ls()) the expression passed is ls(), are evaluated lazily, only if and when needed by the implementation of the called function.

delayedAssign 是一个低级函数,对 R 用户/程序员可见,但它实际上只用于包的延迟加载,用户程序中不需要.delayedAssign 允许指定一个表达式来计算变量的值;仅当/当第一次读取变量时,计算才会延迟发生.

delayedAssign is a low-level function, visible to R users/programmers, but it really is only used for lazy loading of packages and should not be needed in user programs. delayedAssign allows to specify an expression to compute the value of a variable; the computation will happen lazily only if/when the variable is read the first time.

所以,为了回答这个问题,R 中的赋值总是懒惰的",因为使用了写时复制机制.赋值右侧的计算也可以是惰性的(使用 delayedAssign),但用户程序不需要/使用它.

So, to answer the question, an assignment in R is always ''lazy'' in that the copy-on-write mechanism is used. The computation of the right-hand-side of the assignment can be also lazy (using delayedAssign), but that should not be needed/used by user programs.

我认为对于变量的重命名",没有必要使用 delayedAssign(因为没有计算右侧).它只会使情况变得更加复杂,并且可能会由于 delayedAssign 必须进行簿记而导致性能开销.如果我必须重命名变量,我只会使用普通赋值.

I think for the ''renaming'' of variables, there is no need to use delayedAssign (because the right-hand-side is not computed). It only makes the situation more complex and there will likely be performance overhead due to the book-keeping delayedAssign has to do. I would just use ordinary assignment if I had to rename variables.

为了代码清晰,我也会尽可能避免从环境中删除变量,甚至从函数中分配到全局环境中,例如我只会创建一个新列表并将新的绑定(变量)插入其中.

For code clarity, I would also whenever possible try to avoid deleting variables from environments and even assigning from a function into the global environment, e.g. I would just create a new list and insert the new bindings (variables) into it.

已经提到了写时复制机制,对于当前在 GNU-R 中的实现,任何描述的解决方案都可能导致内存复制,如果没有重命名变量,这将是不必要的.在 R 级别无法避免这种情况.

Having mentioned the copy-on-write mechanism, with the current implementation in GNU-R, any of the described solutions will potentially cause memory copying that would not be necessary had the variables not been renamed. There is no way to avoid this at R level.

这篇关于R 中的惰性求值 – 赋值会受到影响吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆