Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
R in Action, Second Edition.pdf
Скачиваний:
540
Добавлен:
26.03.2016
Размер:
20.33 Mб
Скачать

Object-oriented programming

477

To learn more about environments and lexical scoping, see “Environments in R” by Christopher Bare (http://mng.bz/uPYM) and “Lexical Scope and Function Closures in R” by Darren Wilkinson (http://mng.bz/R286).

20.3 Object-oriented programming

R is an object-oriented programming (OOP) language that’s based on the use of generic functions. Each object has a class attribute that is used to determine what code to run when a copy of the object is passed to a generic function such as print(), plot(), or summary().

R has two separate OOP models. The S3 model is older, simpler, and less structured. The S4 model is newer and more structured. The S3 approach is easier to use, and most applications in R use this model. We’ll primarily focus on the S3 model here. The section ends with a brief discussion of the limitations of the S3 model and how the S4 model attempts to address them.

20.3.1Generic functions

R uses the class of an object to determine what action to take when a generic function is called. Consider the following code:

summary(women)

fit <- lm(weight ~ height, data=women) summary(fit)

In the first instance, the summary() function produces descriptive statistics for each variable in the data frame women. In the second instance, summary() produces a description of a linear regression model. How does this happen?

Let’s look at the code for summary():

> summary

function (object, ...) UseMethod("summary")

Now let’s look at the class for the women data frame and the fit object:

>class(women) [1] "data.frame"

>class(fit)

[1] "lm"

The function call summary(women) executes the function summary.data.frame (women) if it exists, or summary.default(women) otherwise. Similarly, summary(fit) executes the function summary.lm(fit) if it exists, or summary.default(fit) otherwise. The UseMethod() function dispatches the object to the generic function that has an extension matching the object’s class.

To list all S3 generic functions available, use the methods() function:

> methods(summary)

 

[1] summary.aov

summary.aovlist

[3]

summary.aspell*

summary.connection

[5]

summary.data.frame

summary.Date

478

 

CHAPTER 20 Advanced programming

[7]

summary.default

summary.ecdf*

 

...output omitted...

[31]

summary.table

summary.tukeysmooth*

[33]

summary.wmc*

 

Non-visible functions are asterisked

The number of functions returned depends on the packages you have installed on your machine. On my computer, separate summary() functions have been defined for 33 classes!

You can view the code for the functions in the previous example by typing their names without the parentheses (summary.data.frame, summary.lm, and summary

.default). Non-visible functions (functions in the methods list followed by asterisks) can’t be viewed this way. In these cases, you can use the getAnywhere() function to view their code. To see the code for summary.ecdf(), type getAnywhere(summary

.ecdf). Viewing existing code is a great way to get ideas for your own functions. You’ve seen classes such as numeric, matrix, data.frame, array, lm, glm, and

table, but the class of an object can be any arbitrary string. Additionally, a generic function doesn’t have to be print(), plot(), or summary(). Any function can be generic. The following listing defines a generic function called mymethod().

Listing 20.2 An example of an arbitrary generic function

> mymethod <- function(x, ...) UseMethod("mymethod")

 

>

mymethod.a

<-

function(x)

print("Using

A")

b Defines a generic

>

mymethod.b

<-

function(x)

print("Using

B")

function

>mymethod.default <- function(x) print("Using Default")

>x <- 1:5

>y <- 6:10

>z <- 10:15

> class(x)

<- "a"

c Assigns classes to objects

> class(y)

<- "b"

 

 

> mymethod(x)

 

 

 

 

[1] "Using

A"

 

 

> mymethod(y)

 

d Applies the generic

[1] "Using

B"

 

function to the objects

> mymethod(z)

 

 

[1] "Using

Default"

 

 

>class(z) <- c("a", "b")

>mymethod(z)

[1] "Using A"

>class(z) <- c("c", "a", "b")

>mymethod(z)

[1] "Using A"

eApplies the generic function to an object with two classes

fGeneric function has no default for class "c"

In this example, mymethod() generic functions are defined for objects of classes a and b. A default() function is also defined b. The objects x, y, and z are then defined,

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]