可以低调地不修改更高范围内的变量 [英] can lapply not modify variables in a higher scope

查看:124
本文介绍了可以低调地不修改更高范围内的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常想要做的基本上如下:
$ b $ pre $ mat $ mat矩阵(0,nrow = 10,ncol = 1)
lapply(1:10,function(i){mat [i,] < - rnorm(1,mean = i)})

但是,我预计mat将会有10个随机数,但它有0(我并不担心rnorm部分。显然有一个权利我担心会影响lapply的匿名函数中的mat)我是否可以不影响lapply中的矩阵mat?为什么不?有没有一个R的作用域规则阻止了这种情况?

解决方案

我在这个相关问题中讨论了这个问题: R的应用家庭超过语法糖。你会注意到,如果你看看 apply 的函数签名,它们有一个关键的区别:a for 循环计算表达式,而 apply 循环计算函数



如果你想改变apply函数范围之外的东西,那么你需要使用<< - 指定。或者更重要的是,改为使用来代替循环。但在处理函数之外的事情时,您确实需要小心,因为这可能会导致意外的行为。

在我看来,使用应用函数的主要原因之一是显式的,因为它不会改变它之外的东西。这是函数式编程的核心概念,其中函数避免使用副作用。这也是为什么 apply 系列函数可以用于并行处理的原因(并且类似的函数存在于各种并行程序包中,例如雪)。



最后,运行代码示例的正确方法是将参数传递给您的函数,然后分配输出:



$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $矩阵(lapply(1:10,函数(i,mat){mat [i,] < - rnorm(1,mean = i)},mat = mat))

在可能的情况下最好明确一个参数(因此 mat = mat )而不是推断它。


I often want to do essentially the following:

mat <- matrix(0,nrow=10,ncol=1)
lapply(1:10, function(i) { mat[i,] <- rnorm(1,mean=i)})

But, I would expect that mat would have 10 random numbers in it, but rather it has 0. (I am not worried about the rnorm part. Clearly there is a right way to do that. I am worry about affecting mat from within an anonymous function of lapply) Can I not affect matrix mat from inside lapply? Why not? Is there a scoping rule of R that is blocking this?

解决方案

I discussed this issue in this related question: "Is R’s apply family more than syntactic sugar". You will notice that if you look at the function signature for for and apply, they have one critical difference: a for loop evaluates an expression, while an apply loop evaluates a function.

If you want to alter things outside the scope of an apply function, then you need to use <<- or assign. Or more to the point, use something like a for loop instead. But you really need to be careful when working with things outside of a function because it can result in unexpected behavior.

In my opinion, one of the primary reasons to use an apply function is explicitly because it doesn't alter things outside of it. This is a core concept in functional programming, wherein functions avoid having side effects. This is also a reason why the apply family of functions can be used in parallel processing (and similar functions exist in the various parallel packages such as snow).

Lastly, the right way to run your code example is to also pass in the parameters to your function like so, and assigning back the output:

mat <- matrix(0,nrow=10,ncol=1)
mat <- matrix(lapply(1:10, function(i, mat) { mat[i,] <- rnorm(1,mean=i)}, mat=mat))

It is always best to be explicit about a parameter when possible (hence the mat=mat) rather than inferring it.

这篇关于可以低调地不修改更高范围内的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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