【问题标题】:Why is using `<<-` frowned upon and how can I avoid it?为什么使用 `<<-` 不受欢迎,我该如何避免呢?
【发布时间】:2012-04-08 17:57:28
【问题描述】:

我关注了关于HERE的讨论,很好奇为什么在R中使用&lt;&lt;-不受欢迎。它会引起什么样的混乱?

我还想要一些关于如何避免&lt;&lt;- 的提示。我经常使用以下内容。例如:

### Create dummy data frame of 10 x 10 integer matrix.
### Each cell contains a number that is between 1 to 6.
df <- do.call("rbind", lapply(1:10, function(i) sample(1:6, 10, replace = TRUE)))

我想要实现的是将每个数字向下移动 1,即所有 2 将变为 1,所有 3 将变为 2,等等。因此,所有 n 将变为 n-1。我通过以下方式实现了这一点:

df.rescaled <- df
sapply(2:6, function(i) df.rescaled[df.rescaled == i] <<- i-1))

在这种情况下,我该如何避免&lt;&lt;-?理想情况下,我希望能够将 sapply 结果传递到另一个变量中:

df.rescaled <- sapply(...)

【问题讨论】:

标签: r


【解决方案1】:

第一点

&lt;&lt;-NOT 分配给全局变量的运算符。它尝试在最近的父环境中分配变量。所以,比如说,这会造成混乱:

f <- function() {
    a <- 2
    g <- function() {
        a <<- 3
    }
}

那么,

> a <- 1
> f()
> a # the global `a` is not affected
[1] 1

第二点

您可以使用Reduce

Reduce(function(a, b) {a[a==b] <- a[a==b]-1; a}, 2:6, df)

apply

apply(df, c(1, 2), function(i) if(i >= 2) {i-1} else {i})

但是

简单地说,这就足够了:

ifelse(df >= 2, df-1, df)

【讨论】:

  • 感谢我的代码的替代方案。非常感激。您能详细说明 Reduce 功能吗?即使在阅读了 ?Reduce 之后,我也不太清楚它的逻辑流程。我可以理解您正在尝试在 Reduce 中创建一个带有 2 个变量的函数。对于a 中的所有人,其中==b 减去1。之后有一个 ;a 和我丢失的其余语法
  • Reduce 也被称为Fold,这是函数式编程中流行的方法。这是一个简单的解释。 wikipedia
【解决方案2】:

您可以将&lt;&lt;- 视为全局赋值(大约,因为正如 kohske 指出的那样,除非变量名存在于更接近的环境中,否则它会分配给顶层环境)。为什么这是不好的例子在这里:

Examples of the perils of globals in R and Stata

【讨论】:

  • &lt;&lt;- 视为检查封闭环境的分配更有意义,因为x &lt;&lt;- value 等效于assign('x', value, inherits=TRUE)。我将它用于与assign('x', value, pos=.GlobalEnv) 完全不同的目的。
猜你喜欢
  • 2016-01-20
  • 2021-04-04
  • 2011-07-05
  • 2015-05-23
  • 1970-01-01
  • 2011-06-15
  • 2019-06-11
  • 2010-10-20
  • 2011-07-10
相关资源
最近更新 更多