Я столкнулся с подобной проблемой и реализовал ее таким образом, используя Base R. Я склонен усложнять себе жизнь, не используя сторонние пакеты, такие как R6.Чтобы решить эту проблему, я получаю доступ к среде, в которой определены методы объекта, и таким образом сохраняю переменные.
В этом примере я пытаюсь реализовать MinMaxScaler, подобный тому, который можно найти в scikit learn:
## Base reference class
setRefClass(
"Transformer",
contains = "VIRTUAL",
methods = list(
fit = function(data) stop("Must implement"),
transform = function(data) stop("Must implement"),
fit_transform = function(data) {
fit(data)
transform(data)
}
))
Конкретная реализация Transformer API.В методе fit
я получаю доступ к среде, в которой определено fit
.Затем я использую эту среду для хранения любых переменных, которые мне нужны для промежуточных вычислений, и для обновления объекта на месте - так же, как sklearn.
MinMaxScaler <-setRefClass(
"MinMaxScaler",
contains = "Transformer",
fields = c(feature_range = "numeric"),
methods = list(
fit = function(data) {
env <- environment(fun = .self$fit)
rng <- range(data, na.rm=TRUE)
env$data_range_ <- diff(range(data, na.rm=TRUE))
env$data_min_ <- rng[[1]]
env$data_max_ <- rng[[2]]
},
transform = function(data) {
env <- environment(fun = .self$transform)
scalef <- diff(range(feature_range))
scalef * (data - env$data_min_) / env$data_range_ + min(feature_range)
}
)
)
Чтобы продемонстрировать этот шаблон, я создам два скейлера и подгону их по отдельности.:
> ## Dummy data
> set.seed(123)
> z <- rnorm(1e4)
> summary(z)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-3.845320 -0.667969 -0.011089 -0.002372 0.673347 3.847768
>
> scaler1 <- MinMaxScaler(feature_range=c(0, 50))
> summary(scaler1$fit_transform(z))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 20.65 24.92 24.98 29.37 50.00
>
> scaler2 <- MinMaxScaler(feature_range=c(-100, 100))
> summary(scaler2$fit_transform(z))
Min. 1st Qu. Median Mean 3rd Qu. Max.
-100.00000 -17.39725 -0.32011 -0.09347 17.47344 100.00000
>
> ## to show the scalers are distinct and not sharing private vars
> summary(scaler1$transform(z))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 20.65 24.92 24.98 29.37 50.00
> summary(scaler2$transform(z))
Min. 1st Qu. Median Mean 3rd Qu. Max.
-100.00000 -17.39725 -0.32011 -0.09347 17.47344 100.00000