All of the work in R is done by functions, down to the lowest level. For example, there's a function named "+" that does addition. There are over 2000 or so functions built in to R, many of which never get called by the user directly but serve to help out other functions.
The default editor in R for Windows is the Notepad and the
major command is fix(). When you enter fix( You can use a different editor if you like. Specify your editor with options(editor= When you leave NotePad, say "Yes" to the question "Do you want to save changes?" (unless you want to discard your changes). Don't "Save As...", just "Save"; R will update your function automatically. Suppose your function is called b, and suppose there's an error in it when you quit the editor. You'll get an message that might like something this:
Two things to remember about arguments:
(i) p1, p2, and p3 are "local" variables. They live only inside the function and they "hide" any p1, p2 or p3 living outside the function. (You can get at the hidden ones with the
get() function, if you really have to, but this will rarely be useful).
(ii) Arguments are passed "by value." That means that no matter what you do to p1, p2, and p3 inside the function, the original items are unaffected. For example:
You return something either by using the return() statement explicity, or implicitly: R will take the last line of the function to be the return value. As a result, the last line of your function should usually not be an assignment statement: you'll get a warning about that. Here's an example of a return value:
The output of the function gets assigned if you ask:
for (i in 1:10) { # do 10 times: note open brace
res <- my.func (i) # Call my.func, pass the value of i on this loop
cat ("i is ", i, " res is", res, "\n") # print to screen
if (i == 2) {
do.special.thing ()
do.another.thing ()
} # end "if"
} # end "for"
Always try to do things with vectors. Loops are expensive in S-PLus.
Exiting NotePad
> fix (b)
Error in edit(name, file, title, editor) :
unexpected '}' occurred on line 4
use a command like
x <- edit()
to recover
If you get this, enter b <- edit (), just as the message suggests. The error messages are not always
the most illuminating but the reason for an error is almost always misplaced parentheses, brackets, braces, or commas.
Writing Functions
When you write an R function there are four things you should keep in mind: the arguments, the code, the side effects, and the return value.
Arguments
The arguments (or parameters) are the pieces of information you pass to the function. They can be of different sorts (lists, numeric vectors, data frames, and so on). Specify them between the parentheses at the top of the function:
function (p1, p2 = 5, p3 = "My String")
{ # function body begins here
This function takes three arguments. Default values are specified for the second and third; if values aren't passed, the values 5 and "My String" will be used for p2 and p3, respectively. There's no default for p1; if no value is passed then the function will fail as soon as a reference
is made to p1. In your function you can check to see whether a argument was passed with the missing() function.
> a <- 1 # Create an object named "a"
#
# This function takes a value and makes it into a 2.
#
> change <- function (x) { x <- 2 }
> change(a) # run the function, passing it a
> a
[1] 1 # a itself is unchanged.
Argument matching
Arguments are "matched" (that is, incoming parameters are assigned to the local variables in your list of arguments) in two ways, first by name and then by position. So consider the function "print.args()":
> print.args <- function (p1, p2, p3) {
cat ("p1 is", p1, ", p2 is", p2, ", p3 is", p3, "\n") }
Technically no braces are required for a one-line function but I always put them in. When you call this function, R matches up the arguments you pass by name first, then it fills the rest by position. For example:
> print.args(p1 = 1, p2 = 2, p3 = 3) # Give them by name
p1 is 1 , p2 is 2 , p3 is 3
> print.args(p3 = 1, p1 = 2, p2 = 3) # Order not important
p1 is 2 , p2 is 3 , p3 is 1
> print.args(3, 1, 2) # Give them by position
p1 is 3 , p2 is 1 , p3 is 2
> print.args(3, 1, p1 = 2) # p1 by name, others by position
p1 is 2 , p2 is 3 , p3 is 1
> print.args(1, 2, 3, 4) # Too many!
Error in print.args(1, 2, 3, 4) : unused argument(s) (4)
Using "..."
The special construct "..." can be used as an argument to signify "anything else." You might, for example, take the parameters passed in this way and hand them off to some function you yourself are calling. This is not something you'll need very often. If you need to figure out what's in the list,
assign list(...) somewhere and check that list out.
Side Effects
By "side effects" we mean anything that the function does besides producing a return value. You function can create or remove objects, but I don't recommend that. The major acceptable side effect is producing graphics.
Return value
Some functions print stuff out, but most return something. In R a function has exactly one return value. If you need to return more than one thing you'll need to make a list (or possibly a matrix, dataframe, or vector, depending). lm(), for example, produces a list.
# some code including the header is above this point....
if (total < 0) # there's a problem
return (-1) # return some value
next.thing <- continue.processing()
remarks <- "Everything worked"
return (list (Out = next.thing, Comment = remarks))
The output from this function will be a list with two components, named Out and Comment.
> sin.of.2 <- sin (2) # number is returned and assigned; nothing prints out
Otherwise it will print to the screen.
If you don't want to return anything you can certainly return(NULL), but that NULL will still print out. If you really don't want anything to print, use invisible(): this says "if I assign the output, go ahead and assign it, but if I don't assign it, don't let it print." So, for example, consider this function:
> log.invis <- function (x) { invisible (log(x))}
> log.invis (3) # Nothing happens!
> a <- log.invis (3) # But it gets assigned
> a
[1] 1.098612