我试图了解如何在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
在R中,面向对象的编程以几种非常不同的方式实现。S3类型的OO是最常用的,因为它非常简单,但是在使似乎相同的函数在不同类型的对象上表现不同时却表现出色。一个很好的参考是Advanced R by Hadley Wickham。
R中的对象具有attributes
。这些属性之一是特殊的class
属性。您可以通过
x <- 1:3
y <- c(1, 2, 3)
class(x) # "integer"
class(y) # "numeric"
S3系统是功能重载系统。定义了一个特殊功能,generic。然后定义其他函数methods,以处理依赖于对象或它们的类的对象。必须定义的方法是默认方法。
这里我用您的示例先定义一个泛型,然后再定义默认方法。
# 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, 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("subracting_1")
subtracting_1 <- function(x){
x <- x - 1
x
}
subtracting_1.list <- function(x, ...){
num <- sapply(x, is.numeric)
x[num] <- lapply(x, 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
也没有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)