R语言 S3类

R语言 S3类

R语言中的所有事物都被认为是对象。对象有属性,与对象相关的最常见的属性是类。命令class用于定义一个对象的类或了解一个对象的类。

Class是一个向量,这个属性允许两件事:

  • 允许对象从众多的类中继承
  • 可以为复杂的类指定继承的顺序

例子。检查一个对象的类

# Creating a vector x consisting of type of genders
x<-c("female", "male", "male", "female")
 
# Using the command <code>class()</code>
# to check the class of the vector
class(x)

输出:

[1] "character"

例子。添加一个对象的类别

# Creating a vector x consisting of type of genders
x<-c("female", "male", "male", "female")
 
# Using the command <code>class()</code>
# to append the class of the vector
class(x)<-append(class(x), "Gender")
class(x)

输出:

[1] "character" "Gender"   

管理内存

在进行面向对象的编程时,程序员可能会对使用哪个类产生疑问–S3还是S4?

当比较这两个类时,S4有一个更结构化的方法,而S3被认为是一个灵活的类。

内存环境负责S3类的灵活性。

一个环境就像一个局部范围,有一个与它相关的变量集。如果知道与环境相关的 “ID”,就可以访问这些变量。

为了知道或设置环境中的变量值,可以使用 assignget 等命令。

例子。在环境中分配和获取变量的值

# Creating a vector x consisting of type of genders
# Creating a vector for age
age<-c(12, 10, 09)
 
# The command environment() can be used
# to bring the pointer to current environment
e <- environment()
e
 
# Setting the value of the variable
assign("age", 3, e)
ls()
 
# Getting the values of the variable
get("age", e)

输出:

[1] "age" "e"   "x"  
[1] 3   

环境可以很容易地被创建。它们也可以被嵌入到其他环境中。

创建一个S3类

S3类是R编程中最普遍和最常用的类。实现这个类很容易,大多数预定义的类都是这种类型的。
一个S3对象基本上是一个列表,它的类属性被分配了一些名字。而创建对象的成员变量是列表的组成部分。
对于创建S3对象,有两个主要步骤:

  • 创建一个带有所需组件的列表(比如x)。
  • 然后通过命令class(x)形成一个类,并为这个类指定一个名字。

例子。可以很容易地创建一个银行账户细节的S3对象。

x <- list(name ="Arjun", account_no = 1234,
          saving = 1500, withdrawn = 234)
class(x)<-"bank"
x
**输出:** 
name
[1] "Arjun"account_no
[1] 1234

saving
[1] 1500withdrawn
[1] 234

attr(, "class")
[1] "bank"

例子。可以很容易地创建一个人的简历的S3对象

x <- list(name ="Arjun", percentage = 95,
          school_name ="ST Xavier")
class(x)<-"resume"
x

输出:

$name
[1] "Arjun"

$percentage
[1] 95

$school_name
[1] "ST Xavier"

attr(, "class")
[1] "resume"

其他语言如PythonJava、C++等对类有适当的定义,对象有适当的定义方法和属性。
,但在R语言的S3类系统中,它是灵活的,你甚至可以修改或转换它们(同一类的对象可以不同)。
R语言的S3系统包括三个主要部分

  • 通用函数
  • 方法
  • 属性

通用函数

R语言非常频繁地使用print()函数。如果你输入类的名称,它的内部结构将被打印出来,或者你可以使用print(类的名称)命令。但是同样的函数print()被用来打印不同的东西,比如–向量、数据框、矩阵等等。

print()是如何识别这些不同的输入的

函数print()是一个通用函数,因此是一个方法的集合。这些方法可以通过输入methods(print)命令进一步检查。

methods(print)

输出:


[1] print.AES* [2] print.Arima* [3] print.AsIs [4] print.Bibtex* [5] print.CRAN_package_reverse_dependencies_and_views* [6] print.DLLInfo [7] print.DLLInfoList [8] print.DLLRegisteredRoutines [9] print.Date [10] print.Dlist [11] print.HoltWinters* [12] print.LaTeX* [13] print.Latex* [14] print.MethodsFunction* [15] print.NativeRoutineList [16] print.PDF_Array* [17] print.PDF_Dictionary* [18] print.PDF_Indirect_Reference* [19] print.PDF_Keyword* [20] print.PDF_Name* [21] print.PDF_Stream* [22] print.PDF_String* [23] print.POSIXct [24] print.POSIXlt [25] print.R6* [26] print.R6ClassGenerator* [27] print.RGBcolorConverter* [28] print.Rcpp_stack_trace* [29] print.Rd* [30] print.SOCK0node* [31] print.SOCKcluster* [32] print.SOCKnode* [33] print.State* [34] print.StructTS* [35] print.TukeyHSD* [36] print.acf* [37] print.anova* [38] print.aov* [39] print.aovlist* [40] print.ar* [41] print.arima0* [42] print.aspell* [43] print.aspell_inspect_context* [44] print.bibentry* [45] print.browseVignettes* [46] print.by [47] print.bytes* [48] print.changedFiles* [49] print.checkDocFiles* [50] print.checkDocStyle* [51] print.checkFF* [52] print.checkRd* [53] print.checkReplaceFuns* [54] print.checkS3methods* [55] print.checkTnF* [56] print.checkVignettes* [57] print.check_Rd_contents* [58] print.check_Rd_line_widths* [59] print.check_Rd_metadata* [60] print.check_Rd_xrefs* [61] print.check_RegSym_calls* [62] print.check_T_and_F* [63] print.check_code_usage_in_package* [64] print.check_compiled_code* [65] print.check_demo_index* [66] print.check_depdef* [67] print.check_details* [68] print.check_details_changes* [69] print.check_doi_db* [70] print.check_dotInternal* [71] print.check_make_vars* [72] print.check_nonAPI_calls* [73] print.check_package_CRAN_incoming* [74] print.check_package_code_assign_to_globalenv* [75] print.check_package_code_attach* [76] print.check_package_code_data_into_globalenv* [77] print.check_package_code_startup_functions* [78] print.check_package_code_syntax* [79] print.check_package_code_unload_functions* [80] print.check_package_compact_datasets* [81] print.check_package_datasets* [82] print.check_package_depends* [83] print.check_package_description* [84] print.check_package_description_encoding* [85] print.check_package_license* [86] print.check_packages_in_dir* [87] print.check_packages_used* [88] print.check_po_files* [89] print.check_so_symbols* [90] print.check_url_db* [91] print.check_vignette_index* [92] print.citation* [93] print.codoc* [94] print.codocClasses* [95] print.codocData* [96] print.colorConverter* [97] print.compactPDF* [98] print.condition [99] print.connection [100] print.data.frame [101] print.default [102] print.dendrogram* [103] print.density* [104] print.difftime [105] print.dist* [106] print.dummy_coef* [107] print.dummy_coef_list* [108] print.ecdf* [109] print.eigen [110] print.factanal* [111] print.factor [112] print.family* [113] print.fileSnapshot* [114] print.findLineNumResult* [115] print.formula* [116] print.fseq* [117] print.ftable* [118] print.function [119] print.getAnywhere* [120] print.glm* [121] print.hclust* [122] print.help_files_with_topic* [123] print.hexmode [124] print.hsearch* [125] print.hsearch_db* [126] print.htest* [127] print.html* [128] print.html_dependency* [129] print.htmlwidget* [130] print.infl* [131] print.integrate* [132] print.isoreg* [133] print.kmeans* [134] print.libraryIQR [135] print.listof [136] print.lm* [137] print.loadings* [138] print.loess* [139] print.logLik* [140] print.ls_str* [141] print.medpolish* [142] print.mtable* [143] print.news_db* [144] print.nls* [145] print.noquote [146] print.numeric_version [147] print.object_size* [148] print.octmode [149] print.packageDescription* [150] print.packageIQR* [151] print.packageInfo [152] print.packageStatus* [153] print.pairwise.htest* [154] print.pdf_doc* [155] print.pdf_fonts* [156] print.pdf_info* [157] print.person* [158] print.power.htest* [159] print.ppr* [160] print.prcomp* [161] print.princomp* [162] print.proc_time [163] print.raster* [164] print.recordedplot* [165] print.restart [166] print.rle [167] print.roman* [168] print.sessionInfo* [169] print.shiny.tag* [170] print.shiny.tag.list* [171] print.simple.list [172] print.smooth.spline* [173] print.socket* [174] print.srcfile [175] print.srcref [176] print.stepfun* [177] print.stl* [178] print.subdir_tests* [179] print.summarize_CRAN_check_status* [180] print.summary.aov* [181] print.summary.aovlist* [182] print.summary.ecdf* [183] print.summary.glm* [184] print.summary.lm* [185] print.summary.loess* [186] print.summary.manova* [187] print.summary.nls* [188] print.summary.packageStatus* [189] print.summary.ppr* [190] print.summary.prcomp* [191] print.summary.princomp* [192] print.summary.table [193] print.summaryDefault [194] print.suppress_viewer* [195] print.table [196] print.tables_aov* [197] print.terms* [198] print.ts* [199] print.tskernel* [200] print.tukeyline* [201] print.tukeysmooth* [202] print.undoc* [203] print.vignette* [204] print.warnings [205] print.xgettext* [206] print.xngettext* [207] print.xtabs*

在上述的长列表中,有一些重要的方法,如print.factor()。当我们通过函数print()打印一个因子时,调用会自动分配给print.factor()
创建的类为-bank,会搜索一个名为print.bank()的方法,由于没有这样的方法存在,所以使用print.default()。
通用函数有一个默认方法,在没有匹配的情况下使用。

创建你自己的方法

创建你自己的方法是可能的。

现在,如果类–‘银行’搜索print.bank(),它会找到这个方法并使用它,如果我们已经创建了它。

x <- list(name ="Arjun", account_no = 1234,
          saving = 1500, withdrawn = 234)
class(x)<-"bank"
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

输出:

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

在一般情况下,创建方法现在可以很容易定义和理解。

  • 首先定义一个存在于类之外的函数(以通用方式)。
  • 其次,一个给定的类定义该函数的具体内容。

基于函数的一个参数的类名和写在相关函数名称中的后缀,R环境决定使用哪个函数。

# Defining a function
indian <- function(eatslunch = TRUE, myFavorite ="daal")
{
    me <- list(haslunch = eatslunch,
               favoritelunch = myFavorite)
 
    # Set the name for the class
    class(me) <- append(class(me), "indian")
    return(me)
}
 
# Reserving the name of the function and
# by using the command <code>UseMethod</code>
# R will search for the appropriate function.
setHaslunch <- function(e, newValue)
{
    print("Calling the base setHaslunch function")
    UseMethod("setHaslunch", e)
    print(" this is not executed")
}
  
setHaslunch.default <- function(e, newValue)
{
    print("This objects is unable to be handled.")
    return(e)
}
 
setHaslunch.indian <- function(e, newValue)
{
    print("R is in setHaslunch.indian and is setting the value")
    ehaslunch <- newValue
    return(e)
}
 
# objects calling functions
foodie <- indian()
foodiehaslunch
foodie <- setHaslunch(foodie, FALSE)
foodie$haslunch

输出:


[1] TRUE [1] "Calling the base setHaslunch function" [1] "R is in setHaslunch.indian and is setting the value" [1] FALSE

属性

对象的属性不影响对象的值,但它们是用于处理对象的额外信息。

函数 attributes() 可以用来查看对象的属性。

例子:一个S3对象被创建,它的属性被显示

# Defining a function
x <- list(name ="Arjun", percentage = 95,
          school_name ="ST Xavier")
attributes(x)

输出:


$names [1] "name" "percentage" "school_name" $class [1] "resume"

另外,你可以通过使用attr,为一个对象添加属性。

# Defining a function
x <- list(name ="Arju", percentage = 95,
          school_name ="ST Xavie")
attr(x, "age")<-c(18)
attributes(x)

输出:

$names
[1] "name"        "percentage"  "school_name"

$age
[1] 18

S3被命名为S3,因为它起源于S语言的第三个版本。S是一种编程语言,后来修改为R和S plus。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程