S-PLUS comes with many functions built in, such as mean
,
log
, lm
and others. S-PLUS also allows you to
create and run your own functions.
To create a function, you must tell S-PLUS how many arguments
the function takes, and what it does. The following series of
commands would create a function of two variables and store
it as my.function
. When a function has finished executing,
it returns the value of its last line, in this case the value
of value.to.return
.
my.function <- function(arg1, arg2) { ... value.to.return }The curly brackets
{ and }
are used to indicate a batch
of commands which should be executed together. The function
command expects to evaluate only one thing, so to evaluate multiple
commands, enclose them in curly brackets.
S-PLUS, for some reason, does not have a standard deviation function. Why not write one?
> stdev <- function(x) + { + sqrt(var(x)) + }(Recall that when an incomplete command has been entered, S-PLUS provides a
+
prompt until the command is completed.) The
curly brackets are not necessary for this function, since it consists of
only one command, but they don't hurt.
To demonstrate how the function works, make up some vector and
try the stdev
function.
> z <- c(1, 2, .45, -1.2, 2.3) > stdev(z) [1] 1.395708Functions are a type of object in S-PLUS, like vectors and data frames. This means they can be manipulated like the other objects.
> is.function(stdev) [1] T > my.stdev <- stdevAssignments within a function have only ``local'' scope. That is, they do not affect the value of any external objects. Consider the following example, in which the value of
test
is
changed within a function, but test
has its original value when
the function is through.
The function changer
takes no arguments and changes the
value of test
to "changed"
. The function then returns
the value of test
.
> test <- "unchanged" > changer <- function() + { + test <- "changed" + test + } > changer() [1] "changed" > test [1] "unchanged"Since
changer
includes two commands, we need the curly brackets
at the beginning and at the end. Also note that the last line of
changer
, test
is what the function returns when it is through
executing.
Sometimes local scope will seem like a good thing to you, since there is no danger of a function doing any unexpected damage to your data. On the other hand, it will sometimes make editing data more complicated than you would like.
If you did actually want to use changer
to change the
value of test
, you could do this:
> test [1] "unchanged" > test <- changer() > test [1] "changed"
For complicated functions, it is helpful to include comments
explaining what the function does. Anything on a line after a #
symbol will be ignored in executing the function, but will show
up when the function is displayed. This means that a line of comments
should be preceded by #
.
> stdev <- function(x) + { + # This function calculates standard deviation + sqrt(var(x)) + } > stdev function(x) { # This function calculates standard deviation sqrt(var(x)) }