R Преобразование нескольких функций в один объект с помощью объектно-ориентированного программирования (S3 и S4)
Я пытаюсь понять, как превратить функции в объектно-ориентированное программирование на R. Так, например, как данные и 2 функции, приведенные ниже, можно превратить в один объект с помощью S3 (а затем S4)? (Может быть, некоторые другие простые данные и функции лучше послужат примерами?)
data <- c(1, 2, 3)
# Function 1
adding_1 <- function(x){
x <- x+1
}
# Function 2
subtracting_1 <- function(x){
x <- x-1
}
И как бы функции ниже выполнялись с использованием ООП.
data1 <- adding_1(data)
data1
data2 <- subtracting_1(data)
data2
1 ответ
В R объектно-ориентированное программирование реализовано несколькими разными способами.
Объектно-ориентированный тип S3 используется чаще всего, потому что он очень прост и все же хорошо справляется с тем, чтобы, казалось бы, одни и те же функции ведут себя по-разному с разными типами объектов. Хорошая ссылка - Advanced R от Hadley Wickham.
В объектах 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
ни 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)