R函数的行为是否会随接收的参数数量而变化?
到目前为止,我已经创建了一个函数,它可以根据是否接收数字或字符作为输入来更改其行为,下面是一个简单的示例:R函数的行为是否会随接收的参数数量而变化?,r,function,class,arguments,polymorphism,R,Function,Class,Arguments,Polymorphism,到目前为止,我已经创建了一个函数,它可以根据是否接收数字或字符作为输入来更改其行为,下面是一个简单的示例: f使用省略号很容易做到: f <- function(x,...) { if(missing(...)) { if(is.numeric(x)) return(x^2) if(is.character(x)) return("Hey, dude. WTF are you doing? Don't give me characters!") }else
f使用省略号很容易做到:
f <- function(x,...)
{
if(missing(...))
{
if(is.numeric(x)) return(x^2)
if(is.character(x)) return("Hey, dude. WTF are you doing? Don't give me characters!")
}else
{
if(any(is.character(c(x,...))) return("Hey, dude. WTF are you doing? Don't give me characters!"))
return(x+..1)
}
}
> f("foo")
[1] "Hey, dude. WTF are you doing? Don't give me characters!"
> f(4)
[1] 16
> f(4,5)
[1] 9
f(“foo”)
[1] “嘿,伙计。你在干什么?别给我角色!”
>f(4)
[1] 16
>f(4,5)
[1] 9
使用省略号很容易做到:
f <- function(x,...)
{
if(missing(...))
{
if(is.numeric(x)) return(x^2)
if(is.character(x)) return("Hey, dude. WTF are you doing? Don't give me characters!")
}else
{
if(any(is.character(c(x,...))) return("Hey, dude. WTF are you doing? Don't give me characters!"))
return(x+..1)
}
}
> f("foo")
[1] "Hey, dude. WTF are you doing? Don't give me characters!"
> f(4)
[1] 16
> f(4,5)
[1] 9
f(“foo”)
[1] “嘿,伙计。你在干什么?别给我角色!”
>f(4)
[1] 16
>f(4,5)
[1] 9
是否可以重写该函数以自己进行检查?e、 g
f <- function(x, y=NA){
if (all(is.numeric(c(x,y))) & !is.na(y)){
return(x+y)
}else if(is.numeric(x)){
return(x^2)
}else if(is.character(x)){
return("Hey, dude. WTF are you doing? Don't give me characters!")
}else{
return("Hey, dude. I don't know what you are giving me?!")
}
}
f是否可以重写函数以自己进行检查?e、 g
f <- function(x, y=NA){
if (all(is.numeric(c(x,y))) & !is.na(y)){
return(x+y)
}else if(is.numeric(x)){
return(x^2)
}else if(is.character(x)){
return("Hey, dude. WTF are you doing? Don't give me characters!")
}else{
return("Hey, dude. I don't know what you are giving me?!")
}
}
f不确定这是否是您需要的,但可能会有帮助:)
更新的函数,因为我没有得到“如果它只是一个数字,则执行一些不同的操作”
背后的逻辑:
如果只有1个参数(var1),可以随意使用它,但请尝试使用Catch,以防它是一个非数值型参数。
如果所有参数都是数字,则将它们相加。
否则返回一些字符串
sum_them <- function(var1, ..., na.rm = F)
{
if(missing(...)) tryCatch({var1 <- var1^2}, warning = function(w){}, error = function(e){})
if(all(is.numeric(c(var1, ...)))) return(sum(c(var1, ...), na.rm = na.rm))
return("non numeric argument")
}
不确定这是否是您需要的,但可能会有所帮助:)
更新的函数,因为我没有得到“如果它只是一个数字,则执行一些不同的操作”
背后的逻辑:
如果只有1个参数(var1),可以随意使用它,但请尝试使用Catch,以防它是一个非数值型参数。
如果所有参数都是数字,则将它们相加。
否则返回一些字符串
sum_them <- function(var1, ..., na.rm = F)
{
if(missing(...)) tryCatch({var1 <- var1^2}, warning = function(w){}, error = function(e){})
if(all(is.numeric(c(var1, ...)))) return(sum(c(var1, ...), na.rm = na.rm))
return("non numeric argument")
}
如果您正在寻找的是类似于C的方法签名[1]的东西,那么不,我不知道R有这种性质的东西
在R中,我所知道的最接近的情况是,有一个“超级函数”,它接受所有参数,然后是一组超级函数分配到的子函数。例如,考虑一下(我在下面所概述的与Juliang-Hn的答案没有什么不同。使用椭圆和显式命名参数之间的区别是对用户可以传递给函数的控制量。如果使用椭圆,则对参数的存在性的测试将看起来不同)
super_function如果您要查找的是类似于C的方法签名[1]的东西,那么不,我不知道R具有这种性质
在R中,我所知道的最接近的情况是,有一个“超级函数”,它接受所有参数,然后是一组超级函数分配到的子函数。例如,考虑一下(我在下面所概述的与Juliang-Hn的答案没有什么不同。使用椭圆和显式命名参数之间的区别是对用户可以传递给函数的控制量。如果使用椭圆,则对参数的存在性的测试将看起来不同)
super\u function如果您想继续使用S3,您可以使用…length()
(>=R 3.4.2):
f如果您想继续使用S3,可以使用…length()
(>=R 3.4.2):
f很难理解到目前为止您已经创建了什么以及您想要实现什么,但我想省略号可能会帮助您:我想要创建f。就我所知,S4类函数就是这么做的,但我从来都不需要它们。很难理解到目前为止您创建了什么以及您想要实现什么,但我想省略号可能会对你有所帮助:我想创建f。据我所知,S4类函数就是这么做的,但我从来都不需要它们。这是一种可能性,但我必须检查的条件数量非常多,我的代码看起来有点混乱这是一种可能性,然而,我必须检查的条件数量非常多,我的代码看起来有点混乱。我认为最终的解决方案将类似于此,根据缺失(…)是真是假调用不同的方法集。这将起作用。省略号在这种情况下非常好,因为您可以在以后轻松添加更多参数。因此,如果您想要一个可以接受3个参数的函数,只需将它们分别引用为.1
和.2
。我认为最终的解决方案将与此类似,根据缺失(…)是真是假调用不同的方法集,这将起作用。省略号在这种情况下非常好,因为您可以在以后轻松添加更多参数。因此,如果您想要一个可以接受3个参数的函数,只需将它们分别引用为.1
和.2
。这可以根据您的喜好进行扩展。您的函数可以通过在非空参数数量不变的所有部分中使用UseMethod()来简化。UseMethod是否不允许您一次只为一个对象指向一个方法?如果我有一个x
类character
,但希望行为根据后续对象的类进行更改,我不确定如何利用它来发挥我的优势?除了处理方法中的所有逻辑之外,它似乎同样是兔子洞。但我愿意接受教育。在所有非空参数数量不变的部分中使用UseMethod()可以简化函数。UseMethod不允许每次只指向一个对象的方法吗?如果我有一个x
类character
,但希望行为根据后续对象的类进行更改,我不确定如何利用它来发挥我的优势?除了处理方法中的所有逻辑之外,它似乎同样是兔子洞。但我愿意接受教育。
> sum_them("test", "this")
[1] "non numeric argument"
> sum_them("test", 10)
[1] "non numeric argument"
> sum_them(5, "this")
[1] "non numeric argument"
> sum_them(5, 10)
[1] 15
> sum_them(NA, 10)
[1] NA
> sum_them(NA, 10, na.rm = T)
[1] 10
> sum_them(NA, na.rm = T)
[1] 0
> sum_them(10, na.rm = T)
[1] 100
> sum_them(10)
[1] 100
> sum_them("test")
[1] "non numeric argument"
> sum_them(10,10,10,10, NA)
[1] NA
> sum_them(10,10,10,10, NA, na.rm = T)
[1] 40
> sum_them(10,10,10,test, NA, na.rm = T)
[1] "non numeric argument"
super_function <- function(x = NULL, y = NULL){
if (!is.null(x) & is.null(y)){
if (is.character(x)){
sub_function_xchar(x)
} else if {
(is.numeric(x)){
sub_function_xnum(x)
}
} else {
sub_function_xelse(x)
}
} else {
if (!is.null(x) & !is.null(y)){
if (is.character(x) & is.character(y)){
sub_function_xychar(x, y)
} else {
# Okay, I think you might get the point now
}
}
}
}
sub_function_xchar <- function(x){
# whatever you want to do with x as a character
}
sub_function_xnum <- function(x){
# whatever you want to do with x as a numeric
}
sub_function_xelse <- function(x){
# whatever you want to do with any other class of x
}
sub_function_xychar <- function(x, y){
# whatever you want to do with x and y as characters
}
f <- function(...)
UseMethod("f")
f.numeric <- function(...)
if(...length() == 1) ..1^2 else sum(...)
f.character <- function(...)
return("Hey, dude. WTF are you doing? Don't give me characters!")
f(2)
#[1] 4
f(3,4)
# [1] 7