Skip to content

Instantly share code, notes, and snippets.

@rpietro
Created August 17, 2013 00:06
Show Gist options
  • Save rpietro/6254541 to your computer and use it in GitHub Desktop.
Save rpietro/6254541 to your computer and use it in GitHub Desktop.
R scripts from Hadley Wickham's chapter on functions
# This is a collection of scripts from Hadley Wickham's chapter on functions at https://github.com/hadley/devtools/wiki/Functions
# Components of a function
f <- function(x) x
f
formals(f) # argument list
body(f) # code inside the function
environment(f) # how variables are found
# Primitive functions call C code directly with .Primitive() and contain no R code
sum
formals(sum)
body(sum)
environment(sum)
## Lexical scoping is how R compares any given symbol to its value.
### Name masking as lexical scoping
f <- function() {
x <- 1
y <- 2
c(x, y)
}
f()
rm(f)
x <- 2
g <- function() {
y <- 1
c(x, y) # if value is not found inside the function it will look one level up
}
g()
rm(x, g)
x <- 1
h <- function() {
y <- 2
i <- function() {
z <- 3
c(x, y, z)
}
i()
}
h()
rm(x, h)
j <- function(x) {
y <- 2
function() {
c(x, y)
}
}
k <- j(1)
k()
rm(j, k)
# functions vs. variables
l <- function(x) x + 1
m <- function() {
l <- function(x) x * 2
l(10)
}
m()
rm(l, m)
n <- function(x) x / 2
o <- function() {
n <- 10
n(n)
}
o()
rm(n, o)
# fresh start
j <- function() {
if (!exists("a")) {
a <- 1
} else {
a <- a + 1
}
print(a)
}
j()
j()
# dynamic lookup
f <- function() x
x <- 15
f()
x <- 20
f()
f <- function() x + 1
codetools::findGlobals(f) #lists all the external dependencies of a function
environment(f) <- emptyenv()
f()
"(" <- function(e1) {
if (is.numeric(e1) && runif(1) < 0.1) {
e1 + 1
} else {
e1
}
}
replicate(100, (1 + 2))
rm("(")
# every operation is a function call
x <- 1
y <- 2
x + y
`+`(x, y)
for (i in 1:3) print(i)
`for`(i, 1:3, print(i))
if (i == 1) print("yes!") else print("no.")
`if`(i == 1, print("yes"), print("no."))
x[3]
`[`(x, 3)
{ print(1); print(2); print(3) }
`{`(print(1), print(2), print(3))
add <- function(x, y) x + y
lapply(1:10, add, 3)
lapply(1:10, `+`, 3)
x <- list(1:3, 4:9, 10:12)
lapply(x, `[`, 2)
# equivalent to
lapply(x, function(x) x[2])
# calling functions
f <- function(abcdef, bcde1, bcde2) {
list(a = abcdef, b1 = bcde1, b2 = bcde2)
}
f(1, 2, 3)
f(2, 3, abcdef = 1)
# Can abbreviate long argument names:
f(2, 3, a = 1)
# Doesn't work because abbreviation is ambiguous
f(1, 3, b = 1)
mean(1:10)
mean(1:10, trim = 0.05)
mean(x = 1:10) # overkill
# below are all confusing
mean(1:10, n = T)
mean(1:10, , FALSE)
mean(1:10, 0.05)
mean(, TRUE, x = c(1:10, NA))
# calling a function given a list of arguments
args <- list(1:10, na.rm = TRUE)
do.call(mean, list(1:10, na.rm = TRUE))
# Equivalent to
mean(1:10, na.rm = TRUE)
# default and missing values
f <- function(a = 1, b = 2) {
c(a, b)
}
g <- function(a = 1, b = a * 2) {
c(a, b)
}
g()
g(10)
h <- function(a = 1, b = d) {
d <- (a + 1) ^ 2
c(a, b)
}
h()
h(10)
h(10, 1)
i <- function(a, b) {
c(missing(a), missing(b))
}
i()
i(a = 1)
i(b = 2)
i(1, 2)
j <- function(a = NULL, b = NULL) {
c(is.null(a), is.null(b))
}
j()
j(a = 1)
j(b = 2)
j(1, 2)
# lazy evaluation: arguments only evaluated if they're used
f <- function(x) {
10
}
system.time(f(Sys.sleep(10)))
f <- function(x) {
force(x)
10
}
system.time(f(Sys.sleep(10)))
add <- function(x) {
function(y) x + y
}
adders <- lapply(1:10, add)
adders[[1]](10)
adders[[10]](10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment