我想编写一个处理多种数据类型的函数。下面是一个有效的例子,但看起来很笨重。是否有标准(或更好)的方式来做到这一点?
(有时我会想念Matlab,其中一切都是一种类型:>)
myfunc = function(x) {
# does some stuff to x and returns a value
# at some point the function will need to find out the number of elements
# at some point the function will need to access an element of x.
#
# args:
# x: a column of data taking on many possible types
# e.g., vector, matrix, data.frame, timeSeries, list
x.vec <- as.vector(as.matrix(as.data.frame(x)))
n <- length(x.vec)
ret <- x.vec[n/3] # this line only for concreteness
return(ret)
}
答案 0 :(得分:6)
使用S3方法。帮助您入门的简单示例:
myfunc <- function(x) {
UseMethod("myfunc",x)
}
myfunc.data.frame <- function(x) {
x.vec <- as.vector(as.matrix(x))
myfunc(x.vec)
}
myfunc.numeric <- function(x) {
n <- length(x)
ret <- x[n/3]
return(ret)
}
myfunc.default <- function(x) {
stop("myfunc not defined for class",class(x),"\n")
}
两个注释:
...
语法将任何其他参数传递给函数。如果你正在扩展现有的S3方法(例如编写像summary.myobject这样的东西),那么包含...
是一个好主意,因为你可以传递常规给予规范函数的参数。 print.myclass <- function(x,...) {
print(x$keyData,...)
}
答案 1 :(得分:3)
嗯,你的功能文档是
# args:
# x: a column of data taking on many possible types
# e.g., vector, matrix, data.frame, timeSeries, list
如果你声称需要提供一个对象,它是不是已经是一个向量而不是矩阵或数据框,因此不需要单独的方法/特定处理?
> dat <- data.frame(A = 1:10, B = runif(10))
> class(dat[,1])
[1] "integer"
> is.vector(dat[,1])
[1] TRUE
> is.vector(dat$A)
[1] TRUE
> is.numeric(dat$A)
[1] TRUE
> is.data.frame(dat$A)
[1] FALSE
我会:
myfunc <- function(x) {
# args:
# x: a column of data taking on many possible types
# e.g., vector, matrix, data.frame, timeSeries, list
n <- length(x)
ret <- x[n/3] # this line only for concreteness
return(ret)
}
> myfunc(dat[,1])
[1] 3
现在,如果您想处理不同类型的对象并提取列,那么S3方法将是一种方法。也许您的示例已经过度简化以供实际使用?无论如何,S3方法将类似于:
myfunc <- function(x, ...)
UseMethod("myfunc", x)
myfunc.matrix <- function(x, j = 1, ...) {
x <- x[, j]
myfunc.default(x, ...)
}
myfunc.data.frame <- function(x, j = 1, ...) {
x <- data.matrix(x)
myfunc.matrix(x, j, ...)
}
myfunc.default <- function(x, ...) {
n <- length(x)
x[n/3]
}
,并提供:
> myfunc(dat)
[1] 3
> myfunc(data.matrix(dat))
[1] 3
> myfunc(data.matrix(dat), j = 2)
[1] 0.2789631
> myfunc(dat[,2])
[1] 0.2789631
答案 2 :(得分:1)
您可能应该尝试使用S3方法编写将处理多种数据类型的函数 这里有一个很好的参考:http://www.biostat.jhsph.edu/~rpeng/biostat776/classes-methods.pdf