Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 2 Functions Trevor A. Branch FISH 553 Advanced R School of Aquatic and Fishery Sciences University of Washington.

Similar presentations


Presentation on theme: "Lecture 2 Functions Trevor A. Branch FISH 553 Advanced R School of Aquatic and Fishery Sciences University of Washington."— Presentation transcript:

1 Lecture 2 Functions Trevor A. Branch FISH 553 Advanced R School of Aquatic and Fishery Sciences University of Washington

2 R scripts vs. functions R scripts containing lots of lines of code are fine for once-off analyses, but would be tedious if you had to repeat the same analysis on many datasets Instead we use functions to code commonly used tasks

3 Properties of functions Functions – Have a name – Are provided with input (“passed” some input) – Do something – Return something for later use Functions can call other functions A program is a collection of functions Functions can be re-used A good function is general, carefully written, and well documented

4 A simple function sin.period <- function(period) { xvals <- seq(from=0, to=2*pi, length=100) yvals <- sin(xvals/period) plot(x=xvals, y=yvals, type="l", lty=1, xaxs="i", lwd=2) } sin.period(period=1) name of function arguments of function R commands which can include calls to other functions start of the function end of the function calling the function passing values to the function arguments

5 pdf("sin period.pdf", width=6, height=6) par(mfrow=c(2,2), mar=c(5,5,2,1)) sin.period(0.25) sin.period(0.5) sin.period(1) sin.period(2) dev.off() Calling the function Note: to beautify this plot, see lecture 8 FISH552 Intro R

6 Inputs to functions Well-designed functions only receive inputs through their arguments myfunc <- function(var1, var2) Some arguments can be optional myfunc <- function(var1=1, var2=0) For the latter case, all of the following function calls will run: myfunc(), myfunc(1,2), myfunc(var2=5) Some built-in R functions (e.g. lm ) have many optional arguments two arguments

7 Hints! Type ls() at the prompt in the console to see all of your current objects, including functions Type the name of a function to see how it was created, e.g. lm, or ?lm for the help file To copy and then change the source code of a built- in function in R, use the edit function, e.g. edit(lm) R contains numerous functions, the trick is finding the right one and being able to understand the documentation

8 Outputs of functions The command return(xx) makes the object xx available to whatever called the function If the function is called from the command line, return(xx) prints out of the object xx Replacing return(xx) with invisible(xx) returns the value without printing out the object xx Functions do not have to return anything You can pass and return all sorts of things: a single number, a vector of numbers, a character, a boolean value, and even another function (!)

9 range1 <- function(xvec) { return(c(min(xvec), max(xvec))) } range2 <- function(xvec) { invisible(c(min(xvec), max(xvec))) } > range1(1:10) [1] 1 10 > range2(1:10) > x1 <- range1(1:10) > x2 <- range2(1:10) > x1 [1] 1 10 > x2 [1] 1 10 range1 uses return range2 uses invisible range2 answer is invisible If assigned to a variable, both functions return the computed value to the variable range1 automatically spits out the answer

10 More complex outputs Often we need to return many values from a function compute.stat <- function(xvec) { ave <- mean(xvec) var <- var(xvec) CV <- sqrt(var)/ave cat(ave, var, CV, "\n") out <- list(ave=ave, var=var, sd=sqrt(var), CV=CV) return(out) } calculate CV = SD/mean prints values to the console create a list with named components return the list

11 Accessing list results > xx <- rnorm(n=100, mean=0, sd=1) > stats <- compute.stat(xvec=xx) 0.02119014 0.9920355 47.00345 > print(stats) $ave [1] 0.02119014 $var [1] 0.9920355 $sd [1] 0.9960098 $CV [1] 47.00345 > print(stats$sd) [1] 0.9960098 access one element of the returned list view the entire returned list the cat() command prints out ave, var, CV

12 Writing to a file write.sin <- function(filename, period) { xvals <- seq(from=0, to=2*pi, length=100) yvals <- sin(xvals/period) outdata <- cbind(xvals, yvals) write.csv(x=outdata, file=filename) } write.sin(filename="sinperiod.csv", period=0.25) one argument is the file name write the results to a file create a matrix of the data pass the name of the intended output file to the function

13 In-class exercise 1 Write a function cor.vec() which takes two vectors X and Y Normalize both (subtract their respective means) so they average 0; plot X versus Y; return the correlation between X and Y Apply your function to the following data set: xx <- seq(from=1, to=100, by=1) yy <- 0.2 + xx*0.5 + rnorm(n=length(xx),mean=0,sd=5) Add,... to your parameters and to the end of the plot() command. The... stands for any parameter Call the function with parameters cex=3 or col="blue"

14 Scope: where is an object “visible” rm(list=ls()) x1 <- 10 func1 <- function(x,y) { print(x) print(y) print(x1) } > func1(x=5, y=6) [1] 5 [1] 6 [1] 10 > print(x) Error in print(x) : object 'x' not found > print(y) Error in print(y) : object 'y' not found variable x1 is available everywhere, it is a global variable x and y are only available inside the function func1, i.e. parameters are local variables

15 First rule of good programming AVOID GLOBAL VARIABLES [whenever possible] Each function should be self-contained All inputs passed as parameters All outputs returned using return() or invisible()

16 More about scope What is the result of this code? rm(list=ls()) #clear everything x1 <- 10 func1 <- function(x) { x1 <- x return(x1) } > func1(x=5) [1] 5 > print(x1) [1] 10

17 Please instantly forget you saw this rm(list=ls()) #clear everything x1 <- 10 func1 <- function(x) { x1 <<- x return(x1) } > func1(x=5) [1] 5 > print(x1) [1] 5 The <<- means change the value of the global variable. NEVER use this.

18 Multiple levels func1 <- function(x) { return(func2(y=x)) } func2 <- function(y) { return(func3(z=y)) } func3 <- function(z) { return(3*z) } > func1(4) [1] 12 > z <- 3 > func1(4) [1] 12 > x <- 2 > func1(4) [1] 12 Scoping rule: if there is a local variable and a global variable with the same name, R will use the local variable

19 Global variables cause subtle bugs func1 <- function(x) { return(func2(y=X)) } func2 <- function(y) { return(func3(z=y)) } func3 <- function(z) { return(3*z) } > func1(4) Error in func3(z = y) : object 'X' not found > X <- 2 > func1(4) [1] 6 lower case x and upper case X are different variables global variable upper case X

20 RStudio conversion to functions y <- 3*x z <- 5*y Select the code and choose the menu option Code->Extract Function, supply a function name. This will convert the code into a function, including arguments for all objects that are required fifteen <- function (x) { y <- 3*x z <- 5*y }

21 In-class exercise 2 Write a function which – Takes a file name and two numbers (the defaults for the two numbers should be 1 and 2) – Reads in a table of data (assume that the file is comma delimited) – Plots the columns represented by the two numbers against each other Hints: – Use the read.csv() or read.table() function – Use print() to check the values of intermediate results (to see if your function is working) – Use the test file "lect2.csv" to check your program

22 In-class exercise 3: π Write a function which – Takes as input a number N representing the highest denominator in the formula above (11 in the above example) – Returns the estimate of pi using the formula – How big does N have to be to obtain π accurate to 5 digits?


Download ppt "Lecture 2 Functions Trevor A. Branch FISH 553 Advanced R School of Aquatic and Fishery Sciences University of Washington."

Similar presentations


Ads by Google