重新定义矩阵的%in%

乔斯利伯

我喜欢能够使用像==这样的运算符在R中的矩阵元素上进行运算|

(m <- matrix(1:4, nrow=2))
#      [,1] [,2]
# [1,]    1    3
# [2,]    2    4

m == 2 | m == 3
#       [,1]  [,2]
# [1,] FALSE  TRUE
# [2,]  TRUE FALSE

不幸的是,%in%它没有同样好的行为,而是返回一个向量而不是一个矩阵:

m %in% c(2, 3)
# [1] FALSE  TRUE  TRUE FALSE

注意到%in%定义为function(x, table) match(x, table, nomatch = 0L) > 0L,我认为我可以重新定义match以获得所需的行为:

match <- function(x, table, nomatch = NA_integer_, incomparables = NULL) {
  m <- base:::match(x, table, nomatch, incomparables)
  if (is.matrix(x)) matrix(m, nrow(x))
  else m
}

如果我显式调用此方法确实有效,则match在运行时仍然无法获得所需的结果m %in% c(2, 3)

match(m, c(2, 3), nomatch=0L) > 0L
#       [,1]  [,2]
# [1,] FALSE  TRUE
# [2,]  TRUE FALSE
m %in% c(2, 3)
# [1] FALSE  TRUE  TRUE FALSE

为什么现在不%in%返回矩阵?

乔斯利伯

感谢@joran向我指出这篇出色的文章,为我澄清了为什么%in%不使用我新定义的match函数。这是我对正在发生的事情的理解:

用户定义的match函数存储在全局环境中,而原始match函数仍存储在namespace:base

environment(match)
# <environment: R_GlobalEnv>
environment(base::match)
# <environment: namespace:base>

现在,考虑当我打电话时会发生什么m %in% c(2, 3)

  1. 这将执行%in%刚刚定义为函数function(x, table) match(x, table, nomatch = 0L) > 0L
  2. 该函数需要找到该match函数,因此它首先在其本地环境中搜索,该本地环境是在函数调用中创建的。match在那里没有定义。
  3. 下一个要寻找的地方match是函数的封闭环境。我们可以弄清楚这是怎么回事:

environment(`%in%`)
# <environment: namespace:base>
  1. 由于的原始版本match(不是用户定义的版本)是在中定义的namespace:base,因此这是所调用函数的版本。

为了使我的矩阵版本%in%能够正常工作,最简单的方法是遵循@Molx的建议并重新定义,%in%以便将其存储在全局环境中(请注意,该函数中还有相同版本namespace:base):

`%in%` <- function(x, table) match(x, table, nomatch = 0L) > 0L
environment(`%in%`)
# <environment: R_GlobalEnv>

现在,m %in% c(2, 3)match首先在其本地函数环境中搜索该函数,然后在封闭的环境(R_GlobalEnv)中搜索该函数,以找到我们用户定义的match函数版本

m %in% c(2, 3)
#       [,1]  [,2]
# [1,] FALSE  TRUE
# [2,]  TRUE FALSE

我们可以%in%使用用户定义match函数的另一种方法是将封闭环境更改base::"%in%"为全局环境:

rm(`%in%`)  # Remove user-defined %in%
environment(`%in%`) <- .GlobalEnv    # Can be reversed with environment(`%in%`) <- asNamespace("base")
m %in% c(2, 3)
#       [,1]  [,2]
# [1,] FALSE  TRUE
# [2,]  TRUE FALSE

正如@Molx答案的评论者所提到的那样,最明智的做法是通过将我的新函数命名为,以避免所有此类头痛%inm%

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章