# STAT_540_R_Lec_03.R # Defining your own functions # see if something is a function is.function(mean) # make your own function logistic <- function(x) exp(x) / (1 + exp(x)) logistic(2) exp(2) / (1 + exp(2)) plot(logistic) plot(logistic, xlim = c(-5,5)) logistic2 <- function(x,a,b) exp(a + b*x)/(1 + exp(a + b*x)) logistic2(2,1,-2) logistic2(x = 2, b = 1,a =-2) # naming the arguments logistic2(2) # set a = 0 and b = 1 as defaults logistic3 <- function(x,a=0,b=1) exp(a + b*x)/(1 + exp(a + b*x)) logistic3(1/2,3,4) logistic3(1/2,a = 3,b = 4) # to plot nice pictures of the function... x <- seq(-5,5,length=100) plot(logistic3(x)~x, type = "l") lines(logistic3(x,a=3,b=-1)~x, col="red") lines(logistic3(x,a=-1,b=2)~x, col="blue") # functions which execute more than one line of code!!!! logistic4 <- function(x,a,b){ # curly braces y <- a + x*b ey <- exp(y) val <- ey / (1 + ey) # this is value I want to return return(val) } logistic3(1,2,3) logistic4(1,2,3) # I want my function to return a list with the value of the function # as well as the values of a and b I used logistic5 <- function(x,a,b){ # curly braces y <- a + x*b ey <- exp(y) val <- ey / (1 + ey) # this is value I want to return output <- list(val = val, a = a, b = b) return(output) } obj <- logistic5(0,-1,1) obj$val obj$a obj$b # this is a BAD way to define a function -- we SHOULD include # a and b as arguments in the function, since they are used # in the function a <- 3 b <- -1 logistic6 <- function(x){ # curly braces y <- a + x*b ey <- exp(y) val <- ey / (1 + ey) # this is value I want to return return(val) } logistic6(1) # Rule of thumb: Every value you use in the function should be # put in as one of the arguments. ## Conditional programming my_birthday <- "01/15" today <- format(Sys.Date(),"%m/%d") if(today == my_birthday){ wish1 <- c("Happy birthday!") wish2 <- c("So glad you were born!") wishes <- c(wish1, wish2) wish <- sample(wishes,1) say <- paste("It is your birthday.", wish) print(say) } else { print("Sorry, it is not your birthday.") } ## else if, to introduce more possibilities bfun <- function(my_birthday){ my_birthday_month <- substr(my_birthday,start = 1,stop =2) # use substr() to extract part of a character string today <- format(Sys.Date(),"%m/%d") today_month <- format(Sys.Date(),"%m") if(today == my_birthday){ wish1 <- c("Happy birthday!") wish2 <- c("So glad you were born!") wishes <- c(wish1, wish2) wish <- sample(wishes,1) say <- paste("It is your birthday.", wish) print(say) } else if(today_month == my_birthday_month){ print("It is not your birthday, but it's your birthday month!") } else { print("Sorry, it is not your birthday.") } } bfun("08/04") bfun("08/28") bfun("01/15") # a piecewise-defined function trifun <- function(x){ if(x < -1){ val <- 0 } else if( (x >= -1) & (x < 0)) { val <- 1 + x } else if( (x >= 0) & (x < 1) ){ val <- 1 - x } else if(x >= 1){ val <- 0 } return(val) } # let's say I want to plot a picture of my function trifun(.5) x <- seq(-2,2,by=.1) trifun(x) # problem here because if() can only take a single logical value -- not a vector # USEFUL FUNCTION: sapply() fx <- sapply(x,FUN = trifun) # evaluates trifun() at each entry in x plot(fx ~ x,type = "l") # take advantage of how logicals can be used as numeric values trifun2 <- function(x) (1 + x) * ((x >= -1) & (x < 0)) + (1-x) * ((x >= 0) & (x < 1)) # handier, because I can give this new function a vector input plot(trifun2(x) ~x,type = "l") # ifelse() x <- 1.5 if( x > 1){ val <- 50 } else { val <- 100 } val ifelse(x > 1,50,-100) x <- .5 ifelse(x > 1,50,-100)