“%op%” 运算符在 IT 技术中代表什么意思?例如,“%in%”?

46

1
请参见https://dev59.com/Y3M_5IYBdhLWcg3wjj4p?rq=1 - Ari B. Friedman
5个回答

58

我认为GSee和Sathish的答案没有深入到足够程度,因为"%"本身就有意义,不仅仅局限于%in%运算符的上下文中。它是用户定义新中缀运算符的机制。这是一个比%in%运算符或其更通用的前缀祖先match更广泛的问题。它可以像创建成对的"s"(um)操作符一样简单:

 `%s%` <- function(x,y) x + y

或者更有趣的是,比如说制作一个二阶导数算子:

 `%DD%` <- function(expr, nam="x") { D(D( bquote(.(expr)), nam), nam) }
 expression(x^4) %DD% "x"
 # 4 * (3 * x^2)

在解析日期、日期时间和C类型格式函数(如strptimeformatCsprintf)时,百分号%字符也具有重要性。

自那时起,我们看到了magrittr包的出现,它带有dplyr修饰符,展示了%括号运算符的另一种用途。

因此,最常见的答案是R解析器会特别处理%符号。由于解析器用于处理绘图数学表达式,在?plotmath帮助页面上还提供了广泛的选项用于图形注释。


1
很好的解释!此外,有用的链接:https://www.datamentor.io/r-programming/infix-operator/ 你知道有没有任何官方文档来解释中缀运算符? - vasili111
2
在R语言定义中搜索“操作符”,“组方法”,“特殊操作符”和“中缀和前缀操作符”。 - IRTFM

39

%op%表示一个infix binary operator。有几个内置的使用%的运算符,你也可以创建自己的运算符。

(在R中,单独的%符号不是关键字。你可以在?Reserved帮助页面上看到关键字列表。)


如何获取关于二进制运算符的帮助?

与任何非标准变量名相同,您必须将术语用引号或反引号括起来。

?"%in%"
?`%in%`    

信用:GSee的回答


%in% 是什么?

如在 ?`%in%` 帮助页面中所述(实际上是 ?match 帮助页面,因为 %in% 只是 match 的中缀版本),

[%in%] 返回逻辑向量,指示其左操作数是否有匹配项

它最常用于分类变量,但也可用于数字。

c("a", "A") %in% letters
## [1]  TRUE FALSE

1:4 %in% c(2, 3, 5, 7, 11)
## [1] FALSE  TRUE  TRUE FALSE

Credit: GSee的回答, Ari的回答, Sathish的回答

如何创建自己的中缀二元运算符?

这些是函数,可以像定义任何其他函数一样定义,但有几个限制。

  1. 它是一个二元运算符,因此该函数必须接受正好两个参数。
  2. 由于名称是非标准的,因此必须使用引号或反引号进行书写。

例如,以下代码定义了一个矩阵幂运算符。

`%^%` <- function(x, y) matrixcalc::matrix.power(x, y)

matrix(1:4, 2) %^% 3

来源:BondedDust的回答, Ari的回答


还有哪些其他的%运算符?

基本 R 语言中:

%/%%% 分别执行整数除法模除法,详细信息请参见?Arithmetic帮助页面。

%o% 给出了数组的外积

%*% 执行矩阵乘法

%x%执行数组的Kronecker积

ggplot2

%+%替换ggplot中的数据框。

%+replace%修改ggplot中的主题元素。

%inside%(内部)检查范围内的值。

%||%(内部)在出现NULL值的情况下提供默认值。此函数还在devtools、reshape2、roxygen2和knitr内部出现。(在knitr中称为%n%。)

magrittr

%>%将左侧内容传递到右侧表达式中。

%<>%将左侧内容传递到右侧表达式中,并将结果赋回到左侧对象中。

%T>%将左侧内容传递到右侧表达式中,仅用于其副作用,返回左侧内容。

%,%构建一个函数序列。

%$%暴露data.frame的列或列表的成员。

data.table:

%between%检查范围内的值。

%chin%类似于%in%,针对字符向量进行了优化。

%like%检查正则表达式匹配。

Hmisc:

%nin% 返回与 %in% 相反的结果。

devtools 中:

%:::% (内部)从作为字符串传递的命名空间中获取变量。

sp 中:

%over% 执行空间连接(例如,哪个多边形对应某些点?)

rebus 中:

%R% 连接 regex 对象的元素。


更普遍地,您可以使用以下命令在计算机上安装的所有软件包中找到所有操作符:
library(magrittr)

ip <- installed.packages() %>% rownames
(ops <- setNames(ip, ip) %>% 
  lapply(
    function(pkg)
    {
      rdx_file <- system.file("R", paste0(pkg, ".rdx"), package = pkg)
      if(file.exists(rdx_file))
      {
        rdx <- readRDS(rdx_file)
        fn_names <- names(rdx$variables)
        fn_names[grepl("^%", fn_names)]
      }
    }
  ) %>% 
  unlist
)

2
精彩的总结。这应该是被接受的答案。 - smci

31

在它周围加上引号以查找帮助页面。 这两者都可以工作。

> help("%in%")
> ?"%in%"

一旦你到达帮助页面,你会看到:

‘%in%’ 当前被定义为

‘"%in%" <- function(x, table) match(x, table, nomatch = 0) > 0’


由于 time 是一个通用函数,我不知道在不知道 X2 的情况下 time(X2) 返回什么。但是,%in% 可以告诉你左手边的项目也在右手边。

> c(1:5) %in% c(3:8)
[1] FALSE FALSE  TRUE  TRUE  TRUE

请参考intersect函数。

> intersect(c(1:5), c(3:8))
[1] 3 4 5

那么:which(time(X2)%in%time(Y))基本上返回X2和Y之间的较大日期吗?感谢两位的回答。 - heavy rocker dude
这并没有回答原问题,关于%op%(自定义中缀运算符),只是回答了示例的含义(并非所问)。‍♂️‍♂️ - ESL

21

更一般地说,%foo% 是二元运算符的语法。在 R 中,二元运算符实际上只是伪装成函数的函数,并且接受两个参数(运算符前面和后面的参数成为函数的前两个参数)。

例如:

> `%in%`(1:5,4:6)
[1] FALSE FALSE FALSE  TRUE  TRUE

%in%虽然在R基础中已定义,但您也可以定义自己的二元函数:

`%hi%` <- function(x,y) cat(x,y,"\n")
> "oh" %hi% "my"
oh my 

另一个类似的用户定义的二元运算符是%%,它执行真正的矩阵乘法,而运算符仅对数据进行向量化计算。 - Sathish
1
@Sathish 已经注意到了,虽然我会称 %*%,%in% 等为“非用户定义”或“内置”运算符。 - Ari B. Friedman
这个答案的直接性非常有帮助,尽管我理解了更高评分的答案。 - Coruscate5

2

%in%是一种操作符,用于在矩阵或数据框中查找和子集化相同名称或值的多个出现。

例如1:使用相同名称进行子集化

set.seed(133)
x <- runif(5)
names(x) <- letters[1:5]
x[c("a", "d")]
#  a         d 
#  0.5360112 0.4231022

现在您可以将“d”的名称更改为“a”

 names(x)[4] <- "a"

如果您尝试使用先前的下标提取相似名称及其值,则不起作用。请注意结果,它没有[1]和[4]的元素。
x[c("a", "a")]

#        a         a 
#    0.5360112 0.5360112 

因此,您可以使用%in%二元运算符从变量中的不同位置提取两个“a”。

names(x) %in% "a"
#  [1]  TRUE FALSE FALSE  TRUE FALSE

#assign it to a variable called "vec"
 vec <- names(x) %in% "a"

#extract the values of two "a"s
 x[vec]
 #         a         a 
 #  0.5360112 0.4231022 

示例2:从一列中获取多个值
请参考此网站的示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接