1

我试图了解如何将函数转换为 R 中的面向对象编程。例如,如何使用 S3(然后是 S4)将下面的数据和 2 个函数转换为一个对象?(也许其他一些简单的数据和函数可以更好地作为示例?)

data <- c(1, 2, 3)

# Function 1
adding_1 <- function(x){
  x <- x+1
}

# Function 2
subtracting_1 <- function(x){
  x <- x-1
}

以及如何使用 OOP 执行以下功能。

data1 <- adding_1(data)
data1
data2 <- subtracting_1(data)
data2
4

1 回答 1

3

在 R 中,面向对象编程以几种非常不同的方式实现。
S3 类型的 OO 是最常用的,因为它非常简单,但在使看似相同的函数在不同类型的对象上表现不同方面做得很好。Hadley Wickham 的 Advanced R是一个很好的参考。

在 R 对象中有attributes. 这些属性之一是特殊class属性。你可以看到这个

x <- 1:3
y <- c(1, 2, 3)
class(x)    # "integer"
class(y)    # "numeric"

S3系统是一个功能重载系统。定义了一个特殊的函数,即泛型。然后定义其他函数,即方法,以根据对象或其类来处理对象。必须定义的方法是默认方法

在这里,我使用您的示例首先定义一个泛型,然后定义默认方法。

# Function 1
adding_1 <- function(x, ...) UseMethod("adding_1")
adding_1.default <- function(x, ...){
  x <- x + 1
  x
}

现在是类"list"和对象的方法"data.frame"

adding_1.list <- function(x, ...){
  num <- sapply(x, is.numeric)
  x[num] <- lapply(x[num], adding_1)
  x
}
adding_1.data.frame <- function(x, ...){
  num <- sapply(x, is.numeric)
  x[num] <- lapply(x[num], adding_1)
  x
}

对于subtracting_1.

# Function 2
subtracting_1 <- function(x, ...) UseMethod("subtracting_1")
subtracting_1.default <- function(x){
  x <- x - 1
  x
}
subtracting_1.list <- function(x, ...){
  num <- sapply(x, is.numeric)
  x[num] <- lapply(x[num], subtracting_1)
  x
}
subtracting_1.data.frame <- function(x, ...){
  num <- sapply(x, is.numeric)
  x[num] <- lapply(x[num], subtracting_1)
  x
}

测试用例。

x作为参数(或y以上)调用时,它是调用的默认方法,因为没有adding_1.integernor adding_1.numeric

也是如此mat

但是,当使用数据框调用时,需要进行特殊处理,以免函数尝试添加1到字符串或可能在数据框中的其他类型的非数字列向量。

mat <- matrix(1:6, 3)
df1 <- data.frame(x = letters[1:5], y = rnorm(5), z = 101:105)

adding_1(x)
adding_1(mat)
adding_1(df1)

subtracting_1(x)
subtracting_1(mat)
subtracting_1(df1)
于 2020-02-08T17:00:41.957 回答