Koji MAKIYAMA (@hoxo_m)
for()
is one of the most popular functions in R. As you
know, it is used to create loops.
For example, let’s calculate squared values for 1 to 3.
for (i in 1:3) {
<- i ^ 2
squared print(squared)
}#> [1] 1
#> [1] 4
#> [1] 9
It is very easy.
However, it becomes too much hassle to change such codes to store the
result. You must prepare some containers with correct length for storing
the result and change print()
to assignment statements.
<- vector("numeric", 3) # prepare a container
result for (i in 1:3) {
<- i ^ 2
squared <- squared # change to assignment
result[i]
}
result#> [1] 1 4 9
Moreover, you may want to store the result as a data.frame with the iteration numbers.
<- data.frame(matrix(nrow = 3, ncol = 2))
result colnames(result) <- c("i", "squared")
for (i in 1:3) {
<- i ^ 2
squared 1] <- i
result[i, 2] <- squared
result[i,
}
result#> i squared
#> 1 1 1
#> 2 2 4
#> 3 3 9
What a bother!
In such or more troublesome situations like that you have to store many variables, the code will grow more complex soon.
The magicfor package makes to resolve the problem being kept readability.
You just add two lines before the for loop. First, load the library.
Second, call magic_for()
. Notice that the main for loop is
kept intact.
library(magicfor) # load library
magic_for(print, silent = TRUE) # call magic_for()
for (i in 1:3) {
<- i ^ 2
squared print(squared)
}
magic_result_as_dataframe() # get the result
#> i squared
#> 1 1 1
#> 2 2 4
#> 3 3 9
magic_for()
takes a function name, and then reconstructs
for()
to remember values passed to the specified function
in for loops. We call it “magicalization”. Once you call
magic_for()
, as you just run for()
as usual,
the result will be stored in memory automatically.
Here, we are using magic_result_as_dataframe()
in order
to get the stored values. It is one of the functions to obtain results
from “magicalized for loops”, and means to take out the results as a
data.frame.
Even if the number of observed variables increases, you can do it the same way.
magic_for(silent = TRUE)
for (i in 1:3) {
<- i ^ 2
squared <- i ^ 3
cubed put(squared, cubed)
}
magic_result_as_dataframe()
#> i squared cubed
#> 1 1 1 1
#> 2 2 4 8
#> 3 3 9 27
put()
is the default function to store values in
magicalized for loops. It allows to take any number of variables and can
display them.
You can install the package from GitHub.
install.packages("devtools") # if you have not installed "devtools" package
::install_github("hoxo-m/magicfor") devtools
You can also use githubinstall package to easy install from GitHub.
install.packages("githubinstall") # if you have not installed "githubinstall" package
::githubinstall("magicfor") githubinstall
The source code for magicfor package is available on GitHub at
The magicfor package provides the functions as follows:
magic_for()
: Magicalize for.magic_free()
: Free magicalization.magic_result()
: as a list.magic_result_as_vetor()
: as a vector.magic_result_as_dataframe()
: as a data.frame.put()
: Display values.In the following, we assume that the library is loaded to use the functions.
library(magicfor)
The main function magic_for()
magicalize for loops.
“Magicalize” means to change the behavior of for()
to store
values outputted via target functions.
magic_for()
for (i in 1:3) {
<- i ^ 2
squared put(squared)
}#> The loop is magicalized with put().
#> squared: 1
#> squared: 4
#> squared: 9
The default target function is put()
. It displays input
values, for example:
<- 1
x put(x)
#> x: 1
You can take out stored values using magic_result_**()
when for loops have finished.
magic_result_as_vector()
#> [1] 1 4 9
magic_for()
magic_for()
has several options.
Specify the first argument func
, you can change target
functions.
magic_for(cat)
for (i in 1:3) {
<- i ^ 2
squared cat(squared, " ")
}#> The loop is magicalized with cat().
#> 1 4 9
If progress = TRUE
, show progress bar.
magic_for(progress = TRUE)
for (i in 1:3) {
<- i ^ 2
squared put(squared)
}
#> |=================================================================| 100%
If you set test
a number, the iteration is limited to
that number of times.
magic_for(test = 2)
for (i in 1:100) {
<- i ^ 2
squared put(squared)
}#> The loop is magicalized with put().
#> squared: 1
#> squared: 4
If silent = TRUE
, target function will be not executed
but only the values will be stored.
If temp = TRUE
, the effect of magicalization will be
lost after once execution of for loop.
magic_for(temp = TRUE)
is_magicalized()
#> [1] TRUE
for (i in 1:3) {
<- i ^ 2
squared put(squared)
}#> The loop is temporary magicalized with put().
#> squared: 1
#> squared: 4
#> squared: 9
is_magicalized()
#> [1] FALSE
magic_free()
You can use magic_free()
to cancel magicalization.
magic_for()
is_magicalized()
#> [1] TRUE
magic_free()
is_magicalized()
#> [1] FALSE
The function also clear the stored values.
magic_for(silent = TRUE)
for (i in 1:3) {
<- i ^ 2
squared put(squared)
}
magic_result_as_vector()
#> [1] 1 4 9
magic_free()
magic_result_as_vector()
#> NULL
magic_result_**()
You can use magic_result_**()
to obtain results from
magicalized for loops.
magic_for(silent = TRUE)
for (i in 1:3) {
<- i ^ 2
squared put(squared)
}
magic_result()
returns results as a list.
magic_result()
#> $squared
#> $squared[[1]]
#> [1] 1
#>
#> $squared[[2]]
#> [1] 4
#>
#> $squared[[3]]
#> [1] 9
magic_result_as_vector()
returns results as a
vector.
magic_result_as_vector()
#> [1] 1 4 9
magic_result_as_dataframe()
returns results as a
data.frame.
magic_result_as_dataframe()
#> i squared
#> 1 1 1
#> 2 2 4
#> 3 3 9
put()
put()
displays input values with high flexibility.
<- 2
x <- 3
y put(x)
#> x: 2
put(x, y)
#> x: 2, y: 3
put(x, x ^ 2, x ^ 3)
#> x: 2, x^2: 4, x^3: 8
put(x, squared = x ^ 2, cubed = x ^ 3)
#> x: 2, squared: 4, cubed: 8
It is very useful for magicfor.
magic_for()
for (i in 1:3) {
put(x = i, squared = i ^ 2, cubed = i ^ 3)
}#> The loop is magicalized with put().
#> x: 1, squared: 1, cubed: 1
#> x: 2, squared: 4, cubed: 8
#> x: 3, squared: 9, cubed: 27
magic_result_as_dataframe(F)
#> x squared cubed
#> 1 1 1 1
#> 2 2 4 8
#> 3 3 9 27
Whenever you put just variables in magicalized for loops, their values will be stored regardless of target functions.
magic_for()
for (i in 1:3) {
<- i ^ 2
squared
squared
}#> The loop is magicalized with put().
magic_result_as_vector()
#> [1] 1 4 9
When you write trarget functions inside of if statements without
else, NA
will be inserted to represent missing.
magic_for()
for (i in 1:3) {
<- i ^ 2
squared if(i == 3) put(squared)
}#> The loop is magicalized with put().
#> squared: 9
magic_result_as_vector()
#> [1] NA NA 9
Target functions work only top level lines or inside of if statements in magicalized for loops. For example, it does not work inside nested for loops.
magic_for()
for (i in 1:2) {
for (j in 1:2) {
put(i, j, i * j)
}
}#> The loop is magicalized with put().
#> i: 1, j: 1, i*j: 1
#> i: 1, j: 2, i*j: 2
#> i: 2, j: 1, i*j: 2
#> i: 2, j: 2, i*j: 4
magic_result_as_vector()
#> list()