我搜索了一个参考,以了解R中的替换函数,但我还没有找到.我试图理解R中替换函数的概念.我有下面的代码,但我不明白它:
"cutoff<-" <- function(x, value){
x[x > value] <- Inf
x
}
Run Code Online (Sandbox Code Playgroud)
然后我们用以下方式调用cutoff:
cutoff(x) <- 65
Run Code Online (Sandbox Code Playgroud)
谁能解释R中的替换功能是什么?
Rei*_*son 49
你打电话的时候
cutoff(x) <- 65
Run Code Online (Sandbox Code Playgroud)
你实际上在打电话
x <- "cutoff<-"(x = x, value = 65)
Run Code Online (Sandbox Code Playgroud)
必须引用函数的名称,因为它是一个语法上有效但非标准的名称,<-
如果没有引用,解析器将解释为操作符而不是函数名称的一部分.
"cutoff<-"()
就像任何其他功能一样(尽管有一个奇怪的名字); 它根据value
(在这种情况下设置任何x
大于65
to Inf
(无限)的值)对其输入参数进行更改.
当您调用这样的函数时,真正的魔力正在完成
cutoff(x) <- 65
Run Code Online (Sandbox Code Playgroud)
因为R正在解析它并拉出各个位以进行上面显示的真实调用.
我们一般都有
FUN(obj) <- value
Run Code Online (Sandbox Code Playgroud)
ř发现功能"FUN<-"()
,并通过将建立呼叫obj
和value
到"FUN<-"()
和安排的结果"FUN<-"()
被分配回obj
,因此,它调用:
obj <- "FUN<-"(obj, value)
Run Code Online (Sandbox Code Playgroud)
对此信息的有用参考是R语言定义第3.4.4节:子集分配 ; 讨论有点倾斜,但似乎是最官方的参考(替换函数在R FAQ(R和S-PLUS之间的差异)中提及,并且在R语言参考(各种技术问题)中,但我没有在官方文件中找到任何进一步的讨论.
Bri*_*ggs 10
Gavin对替换函数的解释提供了很好的讨论.我想提供一个参考,因为您还要求:R语言定义第3.4.4节:子集分配.
作为对已接受答案的补充,我想指出,也可以为非标准函数定义替换函数,即运算符(请参阅 参考资料?Syntax
)和控制流构造。(见?Control
)。
另请注意,为替换功能设计通用和相关联的方法是完全可以接受的。
当定义一个新的类是很常见的定义S3的方法$<-
,[[<-
和[<-
,一些实例是data.table:::`$<-.data.table`
,data.table:::`[<-.data.table`
,或tibble:::`$.tbl_df`
。
但是对于任何其他运算符,我们可以编写替换函数,一些示例:
`!<-` <- function(x, value) !value
x <- NULL # x needs to exist before replacement functions are used!
!x <- TRUE
x
#> [1] FALSE
`==<-` <- function(e1, e2, value) replace(e1, e1 == e2, value)
x <- 1:3
x == 2 <- 200
x
#> [1] 1 200 3
`(<-` <- function(x, value) sapply(x, value, USE.NAMES = FALSE)
x <- c("foo", "bar")
(x) <- toupper
x
#> [1] "FOO" "BAR"
`%chrtr%<-` <- function(e1, e2, value) {
chartr(e2, value, e1)
}
x <- "woot"
x %chrtr% "o" <- "a"
x
#> [1] "waat"
Run Code Online (Sandbox Code Playgroud)
我们甚至可以定义<-<-
,但是如果我们调用x <- y <- z
,解析器将阻止它的使用,因此我们需要使用从左到右的赋值符号
`<-<-` <- function(e1, e2, value){
paste(e2, e1, value)
}
x <- "b"
"a" -> x <- "c"
x
#> [1] "a b c"
Run Code Online (Sandbox Code Playgroud)
有趣的事实,<<-
可以有双重作用
x <- 1:3
x < 2 <- NA # this fails but `<<-` was called!
#> Error in x < 2 <- NA: incorrect number of arguments to "<<-"
# ok let's define it then!
`<<-` <- function(x, y, value){
if (missing(value)) {
eval.parent(substitute(.Primitive("<<-")(x, y)))
} else {
replace(x, x < y, value)
}
}
x < 2 <- NA
x
#> [1] NA 2 3
x <<- "still works"
x
#> [1] "still works"
Run Code Online (Sandbox Code Playgroud)
这些在实践中很少遇到(事实上,我负责我所知道的唯一实际用途,for<-
为我的包pbfor定义),但 R 足够灵活,或者足够疯狂,允许我们定义它们。然而要实际使用它们,由于控制流构造的解析方式,我们需要使用从左到右的赋值->
。
`repeat<-` <- function(x, value) replicate(value, x)
x <- "foo"
3 -> repeat x
x
#> [1] "foo" "foo" "foo"
Run Code Online (Sandbox Code Playgroud)
function<-
function<-
原则上可以定义,但就我所知,我们对此无能为力。
`function<-` <- function(x,value){NULL}
3 -> function(arg) {}
#> Error in function(arg) {: target of assignment expands to non-language object
Run Code Online (Sandbox Code Playgroud)