📜  R编程中的S3类

📅  最后修改于: 2022-05-13 01:54:31.399000             🧑  作者: Mango

R编程中的S3类

R 语言中的所有事物都被视为对象。对象具有属性,与对象相关的最常见的属性是类。命令类用于定义对象的类或了解对象的类。
类是一个向量,这个属性允许做两件事:

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

示例:检查对象的类

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


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


Python3
# 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)


Python3
x <- list(name ="Arjun", account_no = 1234,
          saving = 1500, withdrawn = 234)
class(x)<-"bank"
x


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


Python3
methods(print)


Python3
x <- list(name ="Arjun", account_no = 1234,
          saving = 1500, withdrawn = 234)
class(x)<-"bank"
print.bank<-function(obj)
{
    cat("Name is ", obj$name, "\n")
    cat(obj$account_no, " is the Acc no of the holder\n ")
    cat(obj$saving, " is the amount of saving in the account \n ")
    cat(obj$withdrawn, " is the withdrawn amount\n")
}
x


Python3
# 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 UseMethod
# 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")
    e$haslunch <- newValue
    return(e)
}
 
# objects calling functions
foodie <- indian()
foodie$haslunch
foodie <- setHaslunch(foodie, FALSE)
foodie$haslunch


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


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


输出:

[1] "character"

示例:附加对象的类

Python3

# Creating a vector x consisting of type of genders
x<-c("female", "male", "male", "female")
 
# Using the command class()
# 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等命令。
示例:在环境中分配和获取变量的值

Python3

# 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 对象。

Python3

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

$account_no
[1] 1234

$saving
[1] 1500

$withdrawn
[1] 234

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

示例:可以轻松创建个人简历的 S3 对象。

Python3

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"

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

  • 通用函数
  • 方法
  • 属性

通用函数

R 经常使用 print()函数。如果你输入类的名字,它的内部信息会被打印出来,或者你可以使用命令 print(name of the class)。但是相同的函数print() 用于打印不同的东西,比如向量、数据帧、矩阵等。

print() 如何识别这种不同的输入?

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

Python3

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()。
泛型函数有一个默认方法,当没有匹配可用时使用该方法。

创建自己的方法

创建自己的方法是可能的。
现在如果类 - 'bank' 搜索 print.bank(),它会找到这个方法并使用它,如果我们已经创建了它。

Python3

x <- list(name ="Arjun", account_no = 1234,
          saving = 1500, withdrawn = 234)
class(x)<-"bank"
print.bank<-function(obj)
{
    cat("Name is ", obj$name, "\n")
    cat(obj$account_no, " is the Acc no of the holder\n ")
    cat(obj$saving, " is the amount of saving in the account \n ")
    cat(obj$withdrawn, " 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 环境决定使用哪个函数。

Python3

# 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 UseMethod
# 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")
    e$haslunch <- newValue
    return(e)
}
 
# objects calling functions
foodie <- indian()
foodie$haslunch
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 对象并显示其属性。

Python3

# 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 向对象添加属性。

Python3

# 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 之所以如此命名,是因为它起源于 S 语言的第三版。 S 是一种编程语言,后来修改为 R 和 S plus。