## 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:

drunkenSim <- function(steps = 1000, reps = 10000, close = 0.5,
seed = NULL, table = FALSE) {
if ( !is.null(seed) ) {
set.seed(seed)
}

returns <- numeric(reps)

for (i in 1:reps) {
angle <- runif(steps, 0 , 2*pi)
xSteps <- cos(angle)
ySteps <- sin(angle)

x <- cumsum(xSteps)
y <- cumsum(ySteps)

dist <- sqrt(x^2 + y^2)
closeReturn <- (dist < 0.5)
returns[i] <- sum(closeReturn)
}

if ( table ) {
cat("Here is a table of the number of close returns:\n\n")
tab <- prop.table(table(returns))
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.

drunkenSimList <- function(steps = 1000, reps = 10000, close = 0.5,
seed = NULL, verbose = FALSE) {
if ( !is.null(seed) ) {
set.seed(seed)
}

# get the returns:
returns <- numeric(reps)
for (i in 1:reps) {
angle <- runif(steps, 0 , 2*pi)
xSteps <- cos(angle)
ySteps <- sin(angle)

x <- cumsum(xSteps)
y <- cumsum(ySteps)

dist <- sqrt(x^2 + y^2)
closeReturn <- (dist < 0.5)
returns[i] <- sum(closeReturn)
}
# compute the table and the mean:
tableReturns <- table(returns)
meanReturns <- mean(returns)

# 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:  ",
meanReturns, ".", sep = "")
}

# assemble the desired three items into a list
# (for conveneince, name the items)
results <- list(tableReturns = tableReturns,
meanReturns = meanReturns,
returns = returns)
# return the list
invisible(results)
}

Now we can run the function simply to acquire the simulation results for later use:

simResults <- drunkenSimList(seed = 3939)

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",
simResults\$returns[1:10])
## On the first ten repetitions, the number of close returns were:
##
##   0 6 4 4 2 0 2 5 2 4