我想创建一个重载函数,根据提供的参数,它的行为会有所不同。为此,我需要检查给定的参数是否是现有对象(例如数据框,列表,整数)或抽象公式(例如a + b
,2 * 4
,y ~ x + y
等。) 。下面我粘贴我想要识别的内容:
df <- data.frame(a, b)
f(df) # data.frame
f(data.frame(a, b)) # data frame
f(a + b) # expression
f("a + b") # character
f(2 * 2 + 7) # expression
f(I(2 * 2)) # integer
是否可以构建这样的功能?怎么样?不幸的是,我无法在网上或我知道的R编程书中找到任何参考文献。
在R中重载函数的一般方法是这样的:
f <- function(x) UseMethod("f")
f.default <- function(x) eval(substitute(x))
f.data.frame <- function(x) print("data frame")
它给出了:
> f(df)
[1] "data frame"
> f(2 + 2)
[1] 4
> f(list(a, b))
[[1]]
[1] 1
[[2]]
[1] 2
因此,这样做的问题是我必须命名所有可能的其他数据类型,而不是检查x
是否为表达式。
使用相同:
f2 <- function(x) typeof(substitute(x))
因为它以相同的方式评估函数调用和表达式:
> f2(2 + 2)
[1] "language"
> f2(df)
[1] "symbol"
> f2(data.frame(a, b))
[1] "language"
虽然我希望区分list(a, b)
和2 + 2
,因为第一个是列表,第二个是表达式。
我知道使用R可以轻松识别的经典R公式会很容易,但是可以使用不同的输入吗?
谢谢!
答案 0 :(得分:1)
这是R中面向对象语言的原则。你应该在这里学到更多:
https://www.stat.auckland.ac.nz/~stat782/downloads/08-Objects.pdf http://brainimaging.waisman.wisc.edu/~perlman/R/A1%20Introduction%20to%20object-oriented%20programming.pdf
R中有两种类型的对象:S3和S4。 S3对象更容易实现,更灵活。它们的使用足以满足您的需求。您可以使用 S3通用功能。
我强烈建议您了解有关这些S3和S4类的更多信息,但为了简短起见,您可以查看为函数class
提供的f
参数。这可以通过函数class
完成。
您可以在不同的情况下分离您的函数f
:
f <- function(a){
if (class(a) == 'data.frame'){
# do things...
}
else if (class(a) == 'formula'){
# do things...
}
else if (class(a) == 'integer'){
# do things...
}
else {
stop("Class no supported")
}
}
答案 1 :(得分:0)
if (tryCatch(is.data.frame(x), error=function(z) FALSE)) {
# here do stuff with a data.frame
} else {
# here check the expression using some regular expressions etc.
}