Simulation in R
Helpful tips and tricks in R
In general, for
loops are not the "preferred" route in R.
In general, for
loops are not the "preferred" route in R.
In general, for
loops are not the "preferred" route in R.
sqrt(1:10)
.In general, for
loops are not the "preferred" route in R.
Many functions are vectorized—you can apply a function over a vector.
E.g., the square root of the numbers from 1 to 10: sqrt(1:10)
.
That said, sometimes you just gotta loop.
In general, for
loops are not the "preferred" route in R.
Many functions are vectorized—you can apply a function over a vector.
E.g., the square root of the numbers from 1 to 10: sqrt(1:10)
.
That said, sometimes you just gotta loop.
For these situations, base
R offers a family of apply
functions.
The apply
family applies a function over a vector, list, data frame, etc.
The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
X
A vector/list of values.The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
X
A vector/list of values.FUN
The function you want to evaluate on each value of X
.The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
X
A vector/list of values.FUN
The function you want to evaluate on each value of X
.lapply()
returns a list of the results.
The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
X
A vector/list of values.FUN
The function you want to evaluate on each value of X
.lapply()
returns a list of the results.
Example toupper()
capitalizes characters
The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
X
A vector/list of values.FUN
The function you want to evaluate on each value of X
.lapply()
returns a list of the results.
Example toupper()
capitalizes characters, e.g., toupper("a")
yields "A"
.
The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
X
A vector/list of values.FUN
The function you want to evaluate on each value of X
.lapply()
returns a list of the results.
Example toupper()
capitalizes characters, e.g., toupper("a")
yields "A"
.
lapply(X = c("a", "pig"), FUN = toupper)
The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
X
A vector/list of values.FUN
The function you want to evaluate on each value of X
.lapply()
returns a list of the results.
Example toupper()
capitalizes characters, e.g., toupper("a")
yields "A"
.
lapply(X = c("a", "pig"), FUN = toupper)
returns list("A", "PIG")
.
The apply
family applies a function over a vector, list, data frame, etc.
For example, lapply()
takes two arguments: X
and FUN
.
X
A vector/list of values.FUN
The function you want to evaluate on each value of X
.lapply()
returns a list of the results.
Example toupper()
capitalizes characters, e.g., toupper("a")
yields "A"
.
lapply(X = c("a", "pig"), FUN = toupper)
returns list("A", "PIG")
.
Note This is a silly example, as you can directly use toupper()
on vectors.
The related apply()
function applies a given function (FUN
) along the margins (MARGIN
) of a given array/matrix (X
).
The related apply()
function applies a given function (FUN
) along the margins (MARGIN
) of a given array/matrix (X
).
Your options for MARGIN
are 1
for rows and 2
for columns.
The related apply()
function applies a given function (FUN
) along the margins (MARGIN
) of a given array/matrix (X
).
Your options for MARGIN
are 1
for rows and 2
for columns.
Example Let's find the maximum value in each row of a matrix.
# Create a matrixex_matrix <- matrix(data = 1:16, nrow = 4, byrow = T)# Find the maximum value in each row.apply(X = ex_matrix, MARGIN = 1, FUN = max)
#> [1] 4 8 12 16
Like lapply()
, mapply()
repeatedly evaluates a function (FUN
) for each value in a vector of inputs.
Like lapply()
, mapply()
repeatedly evaluates a function (FUN
) for each value in a vector of inputs.
However, mapply()
allows you to evaluate across multiple vectors.
Like lapply()
, mapply()
repeatedly evaluates a function (FUN
) for each value in a vector of inputs.
However, mapply()
allows you to evaluate across multiple vectors.
In addition mapply()
allows you to dictate whether/how the results are simplified (e.g., SIMPLIFY = T
for vector or matrix) or kept as a list
.
Like lapply()
, mapply()
repeatedly evaluates a function (FUN
) for each value in a vector of inputs.
However, mapply()
allows you to evaluate across multiple vectors.
In addition mapply()
allows you to dictate whether/how the results are simplified (e.g., SIMPLIFY = T
for vector or matrix) or kept as a list
.
Example Random normal draws with different means and variances.
mapply(FUN = rnorm, n = 1, mean = c(0, 10, 20), sd = 1:3)
#> [1] 0.8005418 8.8048199 25.8529457
All of our examples used already-defined functions for FUN
, e.g.,
All of our examples used already-defined functions for FUN
, e.g.,
lapply(X = c("a", "pig"), FUN = toupper)
All of our examples used already-defined functions for FUN
, e.g.,
lapply(X = c("a", "pig"), FUN = toupper)
Alternatively, you define your own function at FUN
, e.g.,
All of our examples used already-defined functions for FUN
, e.g.,
lapply(X = c("a", "pig"), FUN = toupper)
Alternatively, you define your own function at FUN
, e.g.,
lapply(X = 1:2, FUN = function(i) {i > 1})
#> [[1]]#> [1] FALSE#> #> [[2]]#> [1] TRUE
Other packages offer similar (and parallelized) functions.
base
lapply()
apply()
mapply()
Other packages offer similar (and parallelized) functions.
base
lapply()
apply()
mapply()
purrr
/furrr
map()
?
map2()
Other packages offer similar (and parallelized) functions.
base
lapply()
apply()
mapply()
purrr
/furrr
map()
?
map2()
future.apply
future_lapply()
future_apply()
future_mapply()
Other packages offer similar (and parallelized) functions.
base
lapply()
apply()
mapply()
purrr
/furrr
map()
?
map2()
future.apply
future_lapply()
future_apply()
future_mapply()
parallel
mclapply()
mcapply()
mcmapply()
for()
loopsHowever, if you're really committed to running for loops, the syntax is
# Create an empty vectorour_vector <- c()# Run the for loop for some numbersfor (i in c(1, 1, 2, 3, 5, 8)) { # Print 'i' print(i) # Append 'i' to the end of our_vector our_vector <- c(our_vector, i)}
Lists (e.g., as outputted by lapply()
) can be helpful—but they can also be fairly annoying.
Lists (e.g., as outputted by lapply()
) can be helpful—but they can also be fairly annoying. Enter unlist()
.
Lists (e.g., as outputted by lapply()
) can be helpful—but they can also be fairly annoying. Enter unlist()
.
List output
lapply( X = 1:2, FUN = as.character)
#> [[1]]#> [1] "1"#> #> [[2]]#> [1] "2"
Lists (e.g., as outputted by lapply()
) can be helpful—but they can also be fairly annoying. Enter unlist()
.
List output
lapply( X = 1:2, FUN = as.character)
#> [[1]]#> [1] "1"#> #> [[2]]#> [1] "2"
unlist()
-ing to vector
lapply( X = 1:2, FUN = as.character) %>% unlist()
#> [1] "1" "2"
Sometimes you don't want to entirely unlist()
a list.
Sometimes you don't want to entirely unlist()
a list.
For example, you might have a list of data frames that you want to bind into a new data frame.
Sometimes you don't want to entirely unlist()
a list.
For example, you might have a list of data frames that you want to bind into a new data frame.
In this case, you can use bind_rows()
or bind_cols()
from dplyr
.
Sometimes you don't want to entirely unlist()
a list.
For example, you might have a list of data frames that you want to bind into a new data frame.
In this case, you can use bind_rows()
or bind_cols()
from dplyr
.
Alternatively, you might be able to make use of map_dfr()
or map_dfc()
.
Also Don't forget that you can index lists using double-brackets.
# Capitalize the alphabetour_list <- lapply(X = letters, FUN = toupper)# The third letterour_list[[3]]
#> [1] "C"
which()
Finally, the simply function which()
can be surprisingly helpful.
which()
Finally, the simply function which()
can be surprisingly helpful.
which()
tells you which of the entries in a logical vector are TRUE
which()
Finally, the simply function which()
can be surprisingly helpful.
which()
tells you which of the entries in a logical vector are TRUE
, i.e., which element—or elements—satisfies your logical condition(s).
letters
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p"#> [17] "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
letters
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p"#> [17] "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
letters > "m"
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE#> [12] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE#> [23] TRUE TRUE TRUE TRUE
letters
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p"#> [17] "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
letters > "m"
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE#> [12] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE#> [23] TRUE TRUE TRUE TRUE
which(letters > "m")
#> [1] 14 15 16 17 18 19 20 21 22 23 24 25 26
letters
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p"#> [17] "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
letters > "m"
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE#> [12] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE#> [23] TRUE TRUE TRUE TRUE
which(letters > "m")
#> [1] 14 15 16 17 18 19 20 21 22 23 24 25 26
letters[which(letters > "m")]
#> [1] "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
Alternatively, we could have just used the logical vector.
letters
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p"#> [17] "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
letters
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p"#> [17] "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
letters > "m"
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE#> [12] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE#> [23] TRUE TRUE TRUE TRUE
letters
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p"#> [17] "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
letters > "m"
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE#> [12] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE#> [23] TRUE TRUE TRUE TRUE
letters[letters > "m"]
#> [1] "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
This logic-based selection works on many classes of objects, but it may change the class/structure of the object.
# Create a matrixmat <- matrix(1:9, ncol = 3)# Print it outmat
#> [,1] [,2] [,3]#> [1,] 1 4 7#> [2,] 2 5 8#> [3,] 3 6 9
This logic-based selection works on many classes of objects, but it may change the class/structure of the object.
# Create a matrixmat <- matrix(1:9, ncol = 3)# Print it outmat
#> [,1] [,2] [,3]#> [1,] 1 4 7#> [2,] 2 5 8#> [3,] 3 6 9
# Is the entry even?mat %% 2 == 0
#> [,1] [,2] [,3]#> [1,] FALSE TRUE FALSE#> [2,] TRUE FALSE TRUE#> [3,] FALSE TRUE FALSE
This logic-based selection works on many classes of objects, but it may change the class/structure of the object.
# Create a matrixmat <- matrix(1:9, ncol = 3)# Print it outmat
#> [,1] [,2] [,3]#> [1,] 1 4 7#> [2,] 2 5 8#> [3,] 3 6 9
# Is the entry even?mat %% 2 == 0
#> [,1] [,2] [,3]#> [1,] FALSE TRUE FALSE#> [2,] TRUE FALSE TRUE#> [3,] FALSE TRUE FALSE
# Print the even entriesmat[mat %% 2 == 0]
#> [1] 2 4 6 8
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |