为什么使用分配不好?

asb*_*asb 34 r assign

这篇文章(在R中的懒惰评估是指派受影响吗?)涵盖了一些共同点,但我不确定它是否回答了我的问题.

assignapply很久以前发现这个家庭的时候就停止了使用,虽然,纯粹出于以下情况的优雅原因:

names.foo <- letters
values.foo <- LETTERS
for (i in 1:length(names.foo))
  assign(names.foo[i], paste("This is: ", values.foo[i]))
Run Code Online (Sandbox Code Playgroud)

可以替换为:

foo <- lapply(X=values.foo, FUN=function (k) paste("This is :", k))
names(foo) <- names.foo
Run Code Online (Sandbox Code Playgroud)

这也是本(其理由http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-can-I-turn-a-string-into-a-variable_003f)R-FAQ说这应该避免.

现在,我知道这assign通常是不受欢迎的.但还有其他原因我不知道吗?我怀疑它可能会与范围或懒惰的评估混乱,但我不确定?演示此类问题的示例代码将非常棒.

42-*_*42- 30

实际上这两个操作是完全不同的.第一个给你26个不同的对象,而第二个只给你一个.第二个对象在分析中将更容易使用.所以我想我会说你已经证明了它的主要缺点assign,那就是必须总是用它get来收集或收集所有在全球环境中现在"松散"的类似命名的单个对象.尝试想象如何使用这26个单独的对象连续执行任何操作.一个简单的lapply(foo, func)就足够了第二个策略.

常见问题解答引用真的只是说使用赋值然后分配名称更容易,但并不意味着它是"坏".我碰巧把它读作"功能较少",因为你实际上并没有返回一个被赋值的值.该效果看起来是副作用(在这种情况下,该assign策略导致26个单独的副作用).使用的assign似乎由从具有全局变量,避免拿起"真[R路"的方式来语言的人通过,即具有数据对象函数式编程.他们真的应该学习使用列表,而不是用个别命名的项目乱丢他们的工作区.

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

 foo <- setNames(  paste0(letters,1:26),  LETTERS)
Run Code Online (Sandbox Code Playgroud)

这会创建一个命名的原子向量而不是命名列表,但是仍然可以使用给定的名称来访问向量中的值[.

  • +1 - 我认为另一个重点是编写函数时.函数只能返回一个对象,因此列表成为返回多个对象的便捷包装器.如果没有列表,则必须将函数"assign"变量赋予父环境,即具有副作用.这将是非常不满意的. (8认同)
  • apply函数是否在其定义中包含循环.常见的反射是使用apply系列中的函数.这不是矢量化,而是循环隐藏.apply函数在其定义中有一个for循环."lapply函数掩盖了循环,但执行时间往往大致等于显式for循环." R-Inferno Circle 4(过度矢量化) - [链接](http://www.burns-stat.com/pages/Tutor/R_inferno.pdf) (2认同)

Gre*_*now 14

作为fortune(236)我认为我会添加几个例子(也见fortune(174))的来源.

首先,一个测验.请考虑以下代码:

x <- 1
y <- some.function.that.uses.assign(rnorm(100))
Run Code Online (Sandbox Code Playgroud)

运行上面两行代码后,值是x多少?

assign函数用于提交"远距离行动"(参见http://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming)或谷歌).这通常是很难找到错误的根源.

我认为最大的问题assign是它往往会引导人们走上思考的道路,让他们远离更好的选择.一个简单的例子是问题中的2组代码.该lapply解决方案更优雅,应当提倡,但这一事实,人们了解的assign功能让人循环选项.然后他们决定他们需要对循环中创建的每个对象执行相同的操作(这将是另一个简单的lapply或者sapply如果使用优雅的解决方案)并且采用更复杂的循环,包括两者get以及apply丑陋的调用paste.然后那些迷恋assign尝试做类似的事情:

curname <- paste('myvector[', i, ']')
assign(curname, i)
Run Code Online (Sandbox Code Playgroud)

这并没有达到预期的效果,这导致要么抱怨R(抱怨我隔壁邻居的房子离我太远,因为我选择在街区附近走很远)或者更糟糕的是,钻研使用evalparse得到他们构造的字符串"工作"(然后导致fortune(106)fortune(181)).


cbe*_*ica 8

我想指出那assign是与environments 一起使用的意思.

从这一观点来看,该示例中的"坏"的东西上面是使用不太合适的数据结构(基体环境,而不是一个listdata.frame,vector,...).

旁注:也适用于environments,$$<-运算符一起工作,所以在很多情况下,显式的assignget没有必要.

  • 他们诉诸`assign`的通常原因是得到一个构造的变量名,它不能与`$ < - `一起使用.所以我们也应该注意到`[[< - ""适用于环境,所以可以这样做:`myEnv [[paste0("my","Var",1)]] < - value` (4认同)