9.4 Returning Multiple Values
Lists combine many different sorts of objects into one object. This makes them very useful in the context of certain functions.
Consider, for example, the drunken-turtle simulation from Section 6.8:
<- function(steps = 1000, reps = 10000, close = 0.5,
drunkenSim seed = NULL, table = FALSE) {
if ( !is.null(seed) ) {
set.seed(seed)
}
<- numeric(reps)
returns
for (i in 1:reps) {
<- runif(steps, 0 , 2*pi)
angle <- cos(angle)
xSteps <- sin(angle)
ySteps
<- cumsum(xSteps)
x <- cumsum(ySteps)
y
<- sqrt(x^2 + y^2)
dist <- (dist < 0.5)
closeReturn <- sum(closeReturn)
returns[i]
}
if ( table ) {
cat("Here is a table of the number of close returns:\n\n")
<- prop.table(table(returns))
tab print(tab)
cat("\n")
}cat("The average number of close returns was: ",
mean(returns), ".", sep = "")
}
Suppose that we would like to store several of the results of the simulation:
- the vector of the number of close returns on each repetition;
- the table made from the close-returns vector;
- the mean number of returns.
Unfortunately a function can only return one object.
The solution to your problem is to make a list of the three objects we want, and then return the list. We can re-write the function so as to make all output to the console optional. The function will construct the list and return it invisibly.
<- function(steps = 1000, reps = 10000, close = 0.5,
drunkenSimList seed = NULL, verbose = FALSE) {
if ( !is.null(seed) ) {
set.seed(seed)
}
# get the returns:
<- numeric(reps)
returns for (i in 1:reps) {
<- runif(steps, 0 , 2*pi)
angle <- cos(angle)
xSteps <- sin(angle)
ySteps
<- cumsum(xSteps)
x <- cumsum(ySteps)
y
<- sqrt(x^2 + y^2)
dist <- (dist < 0.5)
closeReturn <- sum(closeReturn)
returns[i]
}# compute the table and the mean:
<- table(returns)
tableReturns <- mean(returns)
meanReturns
# handle output to console if user wants it
if ( verbose ) {
cat("Here is a table of the number of close returns:\n\n")
print(prop.table(tableReturns))
cat("\n")
cat("The average number of close returns was: ",
".", sep = "")
meanReturns,
}
# assemble the desired three items into a list
# (for conveneince, name the items)
<- list(tableReturns = tableReturns,
results meanReturns = meanReturns,
returns = returns)
# return the list
invisible(results)
}
Now we can run the function simply to acquire the simulation results for later use:
<- drunkenSimList(seed = 3939) simResults
We can use any of the results at any time and in any way we like:
cat("On the first ten repetitions, the number of close returns were:\n\n\t",
$returns[1:10]) simResults
## On the first ten repetitions, the number of close returns were:
##
## 0 6 4 4 2 0 2 5 2 4