Created
August 17, 2013 00:06
-
-
Save rpietro/6254541 to your computer and use it in GitHub Desktop.
R scripts from Hadley Wickham's chapter on functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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