Chapter 8 Functions, Control Statements, and Loops

Lander's chapter 8-Writing R Functions

Lander's chapter 9-Control Statement

Lander's chapter 10-Loops

###############################
#Chapter 8 writing R functions#
###############################

say.hello <- function()
{print("Hello, World!")}
say.hello()
## [1] "Hello, World!"
sprintf("Hello %s", "Jared")
## [1] "Hello Jared"
hello.person <- function(name)
{print(sprintf("Hello %s", name))}
hello.person("Bob")
## [1] "Hello Bob"
#goes with the function variables' order when variables are not recalled
hello.person <- function(last, first)
{print(sprintf("Hello %s %s", first, last))}
hello.person("Nick", "Wen")
## [1] "Hello Wen Nick"
hello.person(first = "Nick", last = "Wen")
## [1] "Hello Nick Wen"
hello.person(fir="Nick", "Wen")
## [1] "Hello Nick Wen"
hello.person(last = "Wen", "Nick")
## [1] "Hello Nick Wen"
#set default
hello.person <- function(first, last="Wen")
{print(sprintf("Hello, %s %s", first, last))}
hello.person("Nick")
## [1] "Hello, Nick Wen"
#extra arugument
hello.person <- function(first, last="Wen", ...)
{print(sprintf("Hello, %s %s", first, last))}
hello.person("Nick", "Z", "Wen")
## [1] "Hello, Nick Z"
hello.person("Nick", extra="aaa")
## [1] "Hello, Nick Wen"
#return value
double.num <- function(x)
{x*2}
double.num(3)
## [1] 6
double.num <- function(x)
{return(x*2)}
double.num(3)
## [1] 6
#the function with var. is only executed once
double.num <- function(x)
  {7
  return(x*2)
  return(x*7)}
double.num(3)
## [1] 6
#specify the name of a function
run.this <- function(x, func=mean)
{do.call(func, args = list(x))}
run.this(1:10)
## [1] 5.5
run.this(1:10, sd)
## [1] 3.02765
##############################
#chapter 9 Control Statements#
##############################
toCheck <- 1
if(toCheck==1){print("hello")}
## [1] "hello"
if(toCheck==0){print("hello")}

#NOTE: if(){}else must be on the same line
check.bool <- function(x){
  if(x==1){print("hello")}else
    {print("goodbye")}
    }
check.bool(1)
## [1] "hello"
check.bool("k")
## [1] "goodbye"
check.bool(TRUE)
## [1] "hello"
x <- 1
ifelse(x==1, "hello", "goodbye")
## [1] "hello"
#write a function to check a couple of cases
check.bool <- function(x){
  if(x==1){print("Hello")}else 
    if(x==0){
    print("goodbye")
  }else
  {print("confused")}
}
check.bool(1)
## [1] "Hello"
check.bool(0)
## [1] "goodbye"
check.bool("a")
## [1] "confused"
check.bool(4)
## [1] "confused"
#switch--note: it only check for the same type of elements
use.switch <- function(x){
  switch(x,
         "a"="first",
         "b"="second",
         "z"="last",
         "c"="third",
         "other")
}
use.switch("a")
## [1] "first"
use.switch(1)
## [1] "first"
use.switch(12)
use.switch("aaa")
## [1] "other"
is.null(use.switch(12))
## [1] TRUE
#ifelse note: the corresponding result from ifelse is NA if there is NA in the vector
toTest <- c(1,NA,0,1,0,1)
ifelse(toTest==1, toTest*3, "zero")
## [1] "3"    NA     "zero" "3"    "zero" "3"
#compound tests
a <- c(1,1,0,1)
b <- c(2,1,0,1)
#single form checks each element
ifelse(a==1 & b==1, "Yes", "No")
## [1] "No"  "Yes" "No"  "Yes"
#double form checks the first element
ifelse(a==1&&b==1, "Yes", "No")
## [1] "No"
b[1] <- 1
ifelse(a==1&&b==1, "Yes", "No")
## [1] "Yes"
###############################
#practice for ifelse statement#
###############################
#The if statement
x=rnorm(1)
y=rnorm(1)
x>y
## [1] TRUE
if(x>y) {z=x^2; w=30*x} else {z=30*x; w=x^2}

if(x>y) {
  z=x^2
  w=30*x
} else {
  z=30*x
  w=x^2
}

#Look at z and w closely--they're based only on x[1] vs. y[1]
x=rnorm(5)
y=rnorm(5)
x>y
## [1] FALSE FALSE FALSE FALSE  TRUE
if(x>y) {z=x^2; w=30*x} else {z=30*x; w=x^2}
## Warning in if (x > y) {: the condition has length > 1 and only the first element will be used
cbind(x,y,z,w)
##               x          y          z         w
## [1,] -1.1685677  0.6957427 -35.057030 1.3655504
## [2,] -0.7436970 -0.4897608 -22.310910 0.5530852
## [3,] -2.6339780 -0.1214308 -79.019340 6.9378402
## [4,]  0.3055119  1.2489115   9.165356 0.0933375
## [5,]  1.4581000 -2.3324620  43.743000 2.1260556
# use ifelse for elementwise conditional logic:

x=rnorm(5)
y=rnorm(5)
x>y
## [1]  TRUE  TRUE FALSE FALSE  TRUE
z = ifelse(test = x>y, yes = x^2, no = 30*x) #explicitly including argument names
w = ifelse(x>y, 30*x, x^2)

cbind(x,y,z,w)
##               x          y            z         w
## [1,]  0.8292795 -1.2259990   0.68770441 24.878384
## [2,]  1.3171671 -1.8215587   1.73492906 39.515012
## [3,] -0.4232399  0.7812279 -12.69719641  0.179132
## [4,] -1.0557369  0.7250605 -31.67210837  1.114580
## [5,] -0.2695323 -2.2515250   0.07264767 -8.085970
#application of the ifelse statement

matwithNAs <- matrix(c(3,6,NA,7,1,5,NA,NA,10), nrow=3,ncol=3, byrow=T)

mat.replace <- ifelse(is.na(matwithNAs), 0, matwithNAs)

mmp.truncated <-ifelse(mtcars$mpg>20,20,mtcars$mpg)


###########################################
#Chapter 10 Loops, the Un-R way to iterate#
###########################################

for (i in 1:10) {
  print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
print(1:10)
##  [1]  1  2  3  4  5  6  7  8  9 10
fruit <- c("apple", "banana", "pomegranate")
fruitLength <- rep(NA, length(fruit))
fruitLength
## [1] NA NA NA
#it's necessary to give names
names(fruitLength) <- fruit

for (a in fruit) {
  fruitLength[a] <- nchar(a)
}
fruitLength
##       apple      banana pomegranate 
##           5           6          11
fruitLength2 <- nchar(fruit)
names(fruitLength2) <- fruit
fruitLength2
##       apple      banana pomegranate 
##           5           6          11
identical(fruitLength, fruitLength2)
## [1] TRUE
#while
x<-1
while (x<=5) {
  print(x)
  x<-x+1
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
#use of next and break
for (i in 1:10) {
  if(i==3){
    next
  }
  print(i)
}
## [1] 1
## [1] 2
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
#alternatives:
for (i in 1:10) {
  if(i!=3){
    print(i)
  }
}
## [1] 1
## [1] 2
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
for (i in 1:10) {
  if(i==4){
    break
  }
  print(i)
}
## [1] 1
## [1] 2
## [1] 3
#############################
#practice for for and while#
#############################
# for and while loops:

mymat <- matrix(1:16, nc=4)

newmat<-matrix(0, nc=4, nr=4)

for (j in 1:ncol(mymat))
{
  newmat[,j]<-(j+1)*mymat[,j]
}

newmat
##      [,1] [,2] [,3] [,4]
## [1,]    2   15   36   65
## [2,]    4   18   40   70
## [3,]    6   21   44   75
## [4,]    8   24   48   80
j=1;
while (j <= ncol(mymat))
{
  newmat[,j]<-(j+1)*mymat[,j]
  j <- j+1
}

newmat
##      [,1] [,2] [,3] [,4]
## [1,]    2   15   36   65
## [2,]    4   18   40   70
## [3,]    6   21   44   75
## [4,]    8   24   48   80
# Iteration

mymat <- matrix(rnorm(49), nc=7)

rowmaxes=NULL  # or rowmaxes=c()
rowabsmax=NULL
diffabsmax=NULL
for (j in 1:nrow(mymat)) {
  rowmaxes[j]=max(mymat[j,])
  rowabsmax[j]=max(abs(mymat[j,]))
  diffabsmax[j]=rowabsmax[j]-rowmaxes[j]}
hist(diffabsmax)