Unformatted text preview:

Models in S-Plus and R 1 Programming in S Functions Vectorized calculations vs loops As we’ve seen S is a full featured, object-oriented programming language. Previously I’ve shown how you can write scripts and running them from within S-Plus and R. Similarly, it is easy to write your own functions in S-Plus/R General structure of a function function.name <- function(args) { commands function.output }Models in S-Plus and R 2 Function arguments As with any high level language, you need to give the arguments to your function. Well sort of. The argument list will usually be of the form arg1, arg2, arg3 = default3, arg4 = default4 , … As we’ve seen in the past, it is possible to give some arguments default values, as has been done with arg3 and arg4. The first two arguments, arg1 and arg2, since they do not have default settings, they must be given. In addition, it is possible to pass in extra arguments that do not need to be specified ahead of time with “…”. The order that the arguments are listed is the order expected when the function is called. For example testfun <- function(x, y) { x / y } > testfun(1,2) [1] 0.5 > testfun(2,1) [1] 2 > testfun(y=2,x=1) [1] 0.5Models in S-Plus and R 3 > testfun(1) Error in testfun(1) : Argument "y" is missing, with no default testfun2 <- function(x, y = 1, z) { x * y + z} > testfun2(2,1,4) [1] 6 > testfun2(2,z=4) [1] 6 > testfun2(2,,4) # not recommended [1] 6Models in S-Plus and R 4 Local vs global variables Most of the time variables inside functions are treated locally. That is, assignments made inside the function do not affect what is stored succ <- function(n){ n <- n+1 n } > n [1] 2 > succ(n) [1] 3 > n [1] 2 When a function is called and it comes across something that hasn’t been given as an argument or defined earlier in the function it will go through the search path until it finds the objectModels in S-Plus and R 5 testfun3 <- function(x, y = 1, z) { x * y + z * n} > testfun3(2,z=4) [1] 10 While it does have its uses, it can be dangerous and it is usually not recommended. Passing the values in as arguments is usually the way to go. In addition it possible for assignments not to be local, but global. You can reassign values in the first level of the search path from within a function. For example succ2 <- function(n){ x <- n+1 n <<- x x } > n [1] 4 > succ2(n) [1] 5 > n [1] 5Models in S-Plus and R 6 This is very dangerous. DO NOT DO THIS!!!!! Especially with any functions you might pass onto somebody else. You might end up trashing some object you need without realizing it. Control structures (for, if, while, etc) The standard control structures in most high level languages are available in S-Plus/R. The include if statements, for loops, while loops, etc if: The basic structure is if (condition) true branch commands else false branch commands For example fact2<-function(x) { if(x != trunc(x)) {stop("x is not an integer")} else { fact<-1 for(i in 1:x) fact<- fact * i } fact }Models in S-Plus and R 7 In the if statement, the condition should be a single logical value. If you are dealing with vectors, you may not get what you want. An alternative in this case is ifelse. For example > y<- (-1:4) > ylogy <- ifelse(y<=0, 0, y*log(y)) Warning message: NaNs produced in: log(x) > ylogy [1] 0.000000 0.000000 0.000000 1.386294 3.295837 5.545177 switch: When there are more than 2 conditions that you need to deal with, such as with result <- if (test == “Levene”) levene(y, f) else if (test == “Cochran”) cochran(y, f) else bartlett(y, f) it may be easier to deal with as result <- switch(test, Levene = levene(y, f) Cochran = cochran(y, f) Bartlett = Bartlett(y, f))Models in S-Plus and R 8 for: The basic structure is for ( variable in sequence) commands fact1<-function(x) { fact<-1 for(i in 1:x) fact<- fact * i fact } Note that the sequence doesn’t have to be a vector. It could be a list or a data frame, as with > for (i in lcrabs) + print(summary(i)) Min. 1st Qu. Median Mean 3rd Qu. Max. 1.974 2.557 2.744 2.720 2.893 3.140 Min. 1st Qu. Median Mean 3rd Qu. Max. 1.872 2.398 2.549 2.523 2.660 3.006 Min. 1st Qu. Median Mean 3rd Qu. Max. 2.688 3.306 3.469 3.443 3.617 3.863 Min. 1st Qu. Median Mean 3rd Qu. Max. 2.839 3.450 3.605 3.570 3.738 4.000Models in S-Plus and R 9 while: while (condition) commands fact3 <- function(x) { fact <- 1; i <- 1 while (i < x) { i <- i+1 fact <- fact * i } fact} repeat: repeat commands fact4 <- function(x) { fact <- 1; i <- 1 repeat { i <- i+1 fact <- fact * i if (i == x) break } fact} The commands in the repeat loop will continue until a break is seen which will hop you out of the loop.Models in S-Plus and R 10 Error checking When writing functions, it is usually a good idea to check to make sure the input arguments are value. For example, with the factorial functions shown before as all based on a single, integer being input. facte <- function(x) { if (length(x)>1) warning("x should be of length 1, only first component used") if (x[1] <= 0) stop("x must be positive") prod(1:x[1]) } > facte(1:4) [1] 1 Warning message: x should be of length 1, only first component used in: facte(1:4) > facte(-2) Error in facte(-2) : x must be positive warning will allow the function to continue and return output. stop, however will terminate the function, yielding no output. Printing output in functionsModels in S-Plus and R 11 Sometimes it is useful to print results of calculations from within a function, such as during debugging. For example testprint1 <- function(x) { for (i in 1:x) c(i, fact(i)) } > testprint1(4) > You must explicitly print the objects as with testprint2 <- function(x) { for (i in 1:x) print(c(i,fact(i))) } > testprint2(4) [1] 1 1 [1] 2 2 [1] 3 6 [1] 4 24Models in S-Plus and R 12 The functions cat and format is also useful, particularly with formatted output. testprint3 <- function(x) { for (i in 1:x) cat("x = ",i,", ",i,"! = ",fact(i),"\n", sep="") } > testprint3(4) x = 1, 1! = 1 x = 2, 2! = 2 x = 3, 3! = 6 x = 4, 4! = 24Models in S-Plus and R 13 Recursive functions Another approach that can be useful is that of recursive functions. For example, the factorial function can be written as x! = x × (x – 1)! This


View Full Document

HARVARD STAT 335 - Programing_Overheads

Documents in this Course
Load more
Download Programing_Overheads
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Programing_Overheads and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Programing_Overheads 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?