В C ++ мы можем сделать некоторый полиморфизм классов следующим образом:
(спасибо https://www.quora.com/What-is-polymorphism-in-C++-1)
struct Animal{
virtual void speak() const = 0;
};
void doSpeak(const Animal &animal){
animal.speak();
}
struct Cat : public Animal{
void speak() const override{
std::cout << "Miau" << '\n';
}
}
struct Dog : public Animal{
void speak() const override{
std::cout << "Bau" << '\n';
}
}
int main(){
Cat murka;
Dog rex;
doSpeak(murka);
doSpeak(rex);
}
Теперь допустим, что класс Animal
заменен на data.frame
, класс Cat
на my.data.frame
, а метод speak
, который я хочу переопределить, заменен оператором data.frame [
.
Как правильно сделать это на языке R?
Большое спасибо.
РЕДАКТИРОВАТЬ : Извините за длинный пост. Как и требовалось, ниже приведено то, что мне нужно для моего индивидуального класса my.data.frame
. Я использую словарь C ++ (мой родной язык ^^), потому что я не эксперт в R.
my.data.frame
можно построить из реального data.frame
:
mtcars
# mpg cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
# Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
# Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
# Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
# Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
# Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
# ...
class(mtcars)
# [1] "data.frame"
mdf = my.data.frame(mtcars) # Don't know yet how to do that
class(mdf)
# [1] "my.data.frame"
my.data.frame
наследуется от data.frame
, поэтому я могу манипулировать любым экземпляром my.data.frame
точно так же, как если бы это был data.frame
:
names(mdf)
# [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear" "carb"
mdf = mdf[,-9] # Remove "am" column
names(mdf)
# [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "gear" "carb"
merc = rep(0, nrow(mdf)) # Initialize vector of 'Merc flags'
merc[grep("Merc", row.names(mdf))] = 1 # Set to 1 the flag for each 'Merc' car
mdf = cbind(mdf, merc) # Add 'Merc flags' as a new variable
names(mdf)
# [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "gear" "carb" "merc"
my.data.frame
содержит некоторые дополнительные атрибуты (например, атрибут roles
для хранения роли каждой переменной):
attr(mdf, "roles") <- rep("na", ncol(mdf)) # Create roles attribute
attr(mdf, "roles")[1] <- "main" # Use the 'Miles per Gallon' (mpg) variable as *main* variable
attr(mdf, "roles")[ncol(mdf)] <- "filt" # Use the 'Merc flags' vector as a *filter*
attr(mdf, "roles")
# [1] "main" "na" "na" "na" "na" "na" "na" "na" "na" "na" "filt"
- В настоящее время я разрабатываю некоторые функции R, которые используют
my.data.frame
и его дополнительные атрибуты:
# Return the maximum of the main variable within filtered samples
my.max <- function(mdf) {
midx = grep("main", attr(mdf,"roles"))
if (length(midx) == 0)
stop("No main variable defined")
fidx = grep("filt", attr(mdf,"roles"))
if (length(fidx) == 0)
return (max(mdf[,midx]))
else
return (max(mdf[mdf[fidx]==1,midx]))
}
my.max(mdf) # Get the maximum MPG for Merc cars
# [1] 24.4
- Я могу скопировать
my.data.frame
без потери дополнительных атрибутов:
mdf2 = mdf # Simple copy works
attr(mdf2, "roles") # Attribute kept => OK
# [1] "main" "na" "na" "na" "na" "na" "na" "na" "na" "na" "filt"
mdf2 = mdf[-1,] # Copy removing first line
attr(mdf2, "roles") # Attribute kept => OK
# [1] "main" "na" "na" "na" "na" "na" "na" "na" "na" "na" "filt"
mdf2 = mdf[,-8] # Copy removing "vs" column
attr(mdf2, "roles") # Attribute lost => NOK... but WHY ???
# NULL
6- В любое время дополнительная информация my.data.frame
должна соответствовать структуре data.frame
(количество переменных):
mdf = mdf[,-11] # Remove last variable (with role 'filt')
attr(mdf, "roles") # Admitting that roles attribute is kept, I would need the following behavior:
# [1] "main" "na" "na" "na" "na" "na" "na" "na" "na" "na"
my.max(mdf) # Get the maximum MPG for ALL cars
# [1] 33.9
Спасибо за вашу помощь.