首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么使用assign是不好的?

为什么使用assign是不好的?
EN

Stack Overflow用户
提问于 2013-07-10 06:30:05
回答 3查看 9.8K关注 0票数 38

这篇文章(Lazy evaluation in R – is assign affected?)涵盖了一些共同点,但我不确定它是否回答了我的问题。

很久以前,当我发现apply家族时,我就不再使用assign了,尽管纯粹是为了在这样的情况下保持优雅:

代码语言:javascript
复制
names.foo <- letters
values.foo <- LETTERS
for (i in 1:length(names.foo))
  assign(names.foo[i], paste("This is: ", values.foo[i]))

它可以替换为:

代码语言:javascript
复制
foo <- lapply(X=values.foo, FUN=function (k) paste("This is :", k))
names(foo) <- names.foo

这也是(http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-can-I-turn-a-string-into-a-variable_003f) R-faq认为应该避免这种情况的原因。

现在,我知道assign通常是不受欢迎的。但还有其他我不知道的原因吗?我怀疑它可能会打乱作用域或懒惰的评估,但我不确定?演示这类问题的示例代码将会很棒。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-10 06:53:35

实际上,这两个操作是完全不同的。第一个给你26个不同的对象,而第二个只给你一个。第二个对象在分析中会更容易使用。因此,我想我想说您已经演示了assign的主要缺点,即需要始终使用get来围栏或收集所有命名相似的单个对象,这些对象现在在全局环境中是“松散的”。试着想象一下,你将如何连续地使用这26个独立的对象来做任何事情。对于第二种策略,一个简单的lapply(foo, func)就足够了。

FAQ引用实际上只是说使用赋值,然后分配名称更容易,但并不意味着它是“糟糕的”。我碰巧把它理解为“功能较少”,因为你实际上并没有返回一个赋值的值。这种效果看起来是一种副作用(在这种情况下,assign策略会导致26种不同的副作用)。assign的使用似乎被来自具有全局变量的语言的人们所采用,作为一种避免采用"True R Way“的方式,即使用数据对象的函数式编程。他们真的应该学习使用列表,而不是在他们的工作空间中到处都是单独命名的项目。

还有另一个可以使用的赋值范例:

代码语言:javascript
复制
 foo <- setNames(  paste0(letters,1:26),  LETTERS)

这会创建一个命名原子向量,而不是一个命名列表,但对向量中的值的访问仍然是使用为[指定的名称完成的。

票数 35
EN

Stack Overflow用户

发布于 2013-07-11 00:30:09

作为fortune(236)的源代码,我想我应该添加几个示例(也请参阅fortune(174))。

首先,是一个小测验。考虑以下代码:

代码语言:javascript
复制
x <- 1
y <- some.function.that.uses.assign(rnorm(100))

运行上述两行代码后,x的值是什么

assign函数用于提交“远程操作”(参见http://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming)或google )。这通常是很难找到bug的原因。

我认为assign最大的问题是它倾向于引导人们走上思考的道路,让他们远离更好的选择。一个简单的例子是问题中的两组代码。lapply解决方案更优雅,应该推广,但人们了解assign函数这一事实本身就将人们引向了循环选项。然后,他们决定需要在循环中创建的每个对象上执行相同的操作(如果使用优雅的解决方案,这将只是另一个简单的lapplysapply ),并求助于涉及getapply的更复杂的循环以及对paste的丑陋调用。然后,那些迷恋assign的人会尝试这样做:

代码语言:javascript
复制
curname <- paste('myvector[', i, ']')
assign(curname, i)

这并不完全符合他们的预期,这会导致他们抱怨R(这与抱怨我隔壁邻居的家太远一样公平,因为我选择绕着街区走很长一段路),或者更糟糕的是,钻研使用evalparse来让他们构造的字符串“工作”(然后通向fortune(106)fortune(181))。

票数 14
EN

Stack Overflow用户

发布于 2013-07-10 14:58:41

我想指出的是,assign是用来和environment一起使用的。

从这个角度来看,上面示例中的“坏”事情是使用了不太合适的数据结构(基本环境而不是listdata.framevector等)。

附注:同样对于environment$$<-运算符也有效,因此在许多情况下,显式的assignget也不是必需的。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17559390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档