在 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.integer
nor 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)