编写函数来处理R / Splus中的多种数据类型?

时间:2011-03-31 21:54:16

标签: r types

我想编写一个处理多种数据类型的函数。下面是一个有效的例子,但看起来很笨重。是否有标准(或更好)的方式来做到这一点?

(有时我会想念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)
}

3 个答案:

答案 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")
}

两个注释:

  1. ...语法将任何其他参数传递给函数。如果你正在扩展现有的S3方法(例如编写像summary.myobject这样的东西),那么包含...是一个好主意,因为你可以传递常规给予规范函数的参数。
  2. print.myclass <- function(x,...) { print(x$keyData,...) }

    1. 你可以从其他功能调用函数,保持良好和简约。

答案 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