R语言 多态性
R语言在不断发展,它实现了参数化多态性,这意味着R语言中的方法 指的是函数,而不是类。 参数多态性主要是让你为你还没有定义的对象类型定义一个通用的方法或函数,而且可能永远不会定义。这意味着,人们可以为几个具有不同参数集和来自不同类的函数使用相同的名称。R的方法调用机制是泛型,它允许注册某些名称在R中被视为方法,它们充当调度器。
泛型函数
R中的多态性可以通过泛型获得。它允许某些名字被当作方法来处理,它们作为调度器。让我们借助 plot() 函数和 summary 函数来理解。在R编程中, plot() 和 summary() 函数根据传递给它们的对象返回不同的结果,这就是为什么它们是实现多态性的通用函数。
R语言中的plot()
plot() 是R中实现多态性的通用函数之一。如果给它一个向量、一个因子、一个数据框等,它就会产生不同的图形。但是你有没有想过,向量或因子的类别是如何决定用于绘制的方法的呢? 让我们看看plot函数的代码。
例子: plot函数的代码
plot
输出
function (x, y, ...)
UseMethod("plot")
我们可以看到,plot函数的主体只包含一个表达式,那就是UseMethod(“plot”)。让我们在help()函数的帮助下看看UseMethod的定义。
例子: help()方法的定义。
help(UseMethod)
输出
从上面的输出中,我们可以看到UseMethod需要两个参数 generic 和 object。
- generic是字符串名称,是函数的名称(本例中是情节)。
- 这是一个对象,它的类将决定将被 “派发 “的方法,它的意思是泛型方法将被调用的对象。
然后UseMethod通过创建一个类型为plot.object的字符串来搜索需要被调用的合适的plot函数。我们还可以看到该绘图函数的所有可用方法。
例子
methods(plot)
输出
让我们看看 plot( )函数如何接受参数并显示不同的输出。
输入是一个数字向量
在这个例子中,让我们在 plot() 函数中取一个单一的数字向量作为参数。
# R program to illustrate
# polymorphosim
# X Window System Graphics (X11)
X11(width = 15, height = 13)
# The runif() function generates
# random deviates of the uniform distribution
x <- 3 * runif(40) + (1:30)
par(mar = c(20, 20, 1, 1))
# type='l' is used to connect the points
# of the scatter plots with lines.
plot(x, type = 'l', col = '#343deb')
# We can do mouse click or enter pressed
z <- locator(1)
输出
输入是两个数字向量
我们需要传递两个向量参数,它就会相应地产生一个散点图。
# R program to illustrate
# polymorphosim
# X Window System Graphics (X11)
X11(width = 5, height = 3)
# The runif() function generates random
# deviates of the uniform distribution
x <- runif(20)
y <- runif(20) * x
par(mar = c(2, 2, 0.3, 0.3))
# type = 'p' means as points, the output comes as scattered
# pch stands for plot character. pch = 16 we get . character
plot(x, y, type = 'p', pch = 16, col = '#ab1ab0')
#Either mouse press or enter key press wait
z <- locator(1)
输出
输入是一个因子
如果我们传递因子作为参数,那么我们会得到一个条形图模式。
# R program to illustrate
# polymorphosim
# X Window System Graphics (X11)
X11(width = 5, height = 8)
# here fruits names are passed and barchart is produced as output
f <- factor(c('apple', 'orange', 'apple', 'pear', 'orange',
'apple', 'apple', 'orange'))
par(mar = c(2, 2, 0.6, 0.6))
# Using plot()
plot(f, col = '#8f4c91')
z <- locator(1)
输出
输入是一个数据框
Plot函数以数据框为参数,数据框中的每个变量都被绘制成相互对照的图形。
# R program to illustrate
# polymorphosim
# X Window System Graphics (X11)
X11(width = 6, height = 6)
set.seed(280870)
x <- c(4, 3, 1, 2, 2, 4, 6, 4, 5, 5,
4, 4, 5, 4, 4, 8, 4, 1, 2, 7)
y <- x * rnorm(20, 1, 0.3)
z <- x * y
# Taking a data frame
df <- data.frame(x, y, z)
par(mar = c(0.1, 0.1, 0.1, 0.1))
# Using plot()
plot(df, col = '#a832a6', pch = 16, cex = 1.5)
z <- locator(1)
输出
R中的summary()
它也是一个在R中实现多态性的通用函数,用来产生各种模型拟合函数的结果总结。
例子1 :
# R program to illustrate
# polymorphosim
# Rainbow colors and let us see summary of it
colors <- c("violet", "indigo", "blue", "green",
"yellow", "orange", "red")
summary(colors)
输出
Length Class Mode
7 character character
例2 :
让我们检查一下state.region的汇总结果。在R中,通常会显示 “东北部”、”南部”、”中北部 “和 “西部 “下有哪些地区。使用 summary() 函数,可以把state.region作为第一参数,作为第2步,(可以选择)传递 “maxsum “参数。”maxsum “表示在输出中应该显示多少个因素的级别。
# R program to illustrate
# polymorphosim
state.region
# Provides summarised results under each region
summary(state.region)
# As maxsum is given as 3, totally we should have 3 regions
# But here we have 4 regions and hence highest count region,
# next highest count region is displayed and the other
# regions are clubbed under Other
summary(state.region, maxsum = 3)
输出
> state.region
[1] South West West South West West
[7] Northeast South South South West West
[13] North Central North Central North Central North Central South South
[19] Northeast South Northeast North Central North Central South
[25] North Central West North Central West Northeast Northeast
[31] West Northeast South North Central North Central South
[37] West Northeast Northeast South North Central South
[43] South West Northeast South West South
[49] North Central West
Levels: Northeast South North Central West
> summary(state.region)
Northeast South North Central West
9 16 12 13
> summary(state.region, maxsum = 3)
South West (Other)
16 13 21
例3 :
如果数据集非常大,那么我们来看看 summary() 函数是如何工作的。
# R program to illustrate
# polymorphosim
# 10 different data sets are taken using stats::rnorm
x <- stats::rnorm(10)
x
# Let us cut the dataset to lie between -3 and 3 and
# in this case, it will be
# (-3,-2] (-2,-1] (-1,0] (0,1] (1,2] (2,3]
c <- cut(x, breaks = -3:3)
c
# Summarized the available dataset under the given levels
summary(c)
输出
> x
[1] 0.66647846 -0.29140286 -0.29596477 -0.23432541 -0.02144178 1.56640107 0.64575227
[8] -0.23759734 0.73304657 -0.04201218
> c
[1] (0,1] (-1,0] (-1,0] (-1,0] (-1,0] (1,2] (0,1] (-1,0] (0,1] (-1,0]
Levels: (-3,-2] (-2,-1] (-1,0] (0,1] (1,2] (2,3]
> summary(c)
(-3,-2] (-2,-1] (-1,0] (0,1] (1,2] (2,3]
0 0 6 3 1 0
到目前为止,我们已经描述了 plot() 和 summary() 函数,这是一个多态的函数。通过不同的输入, plot() 函数的行为会发生变化并产生输出。这里我们可以看到多态性的概念。同样地,在 summary() 函数中,通过不同的参数,同样的方法适用于提供不同的统计输出。现在让我们来创建自己的泛型方法。
创建泛型方法
让我们创建一个bank类,并尝试创建我们自己的 display() 方法,该方法将使用print()方法,并将以我们指定的格式显示该类的内容。
要做到这一点,我们首先要创建一个通用的display()函数,它将使用UseMethod函数。
display <- function(obj){
UseMethod("print")
}
在创建了通用显示函数后,让我们为我们的类库创建显示函数。
print.bank<-function(obj)
{
cat("Name is ", objname, "\n")
cat(objaccount_no, " is the Acc no of the holder\n ")
cat(objsaving, " is the amount of saving in the account \n ")
cat(objwithdrawn, " is the withdrawn amount\n")
}
现在,让我们看看这个函数给出的输出结果
x <- list(name ="Arjun", account_no = 1234,
saving = 1500, withdrawn = 234)
class(x)<-"bank"
display <- function(obj){
UseMethod("print")
}
print.bank<-function(obj)
{
cat("Name is ", objname, "\n")
cat(objaccount_no, " is the Acc no of the holder\n ")
cat(objsaving, " is the amount of saving in the account \n ")
cat(objwithdrawn, " is the withdrawn amount\n")
}
display(x)
输出
Name is Arjun
1234 is the Acc no of the holder
1500 is the amount of saving in the account
234 is the withdrawn amount