Reading Each Row in List for for Loop
I need your help!
If you find any typos, errors, or places where the text may be improved, please let me know. The all-time ways to provide feedback are by GitHub or hypothes.is annotations.
Opening an issue or submitting a pull request on GitHub
                        Adding an annotation using hypothes.is.       To add an annotation,            select some text            and and so click the                        on the popular-up carte.       To see the annotations of others, click the                        in the upper correct-hand corner of the page.          
Iteration
Introduction
The microbenchmark package is used for timing code.
The                map()                function appears in both the purrr and maps packages. See the "Prerequisites" section of the Introduction. If you lot see errors similar the following, y'all are using the wrong                map()                function.
                > map(c(TRUE, Fake, TRUE), ~ !.) Error: $ operator is invalid for atomic vectors > map(-2:two, rnorm, north = 5) Error in map(-2:two, rnorm, n = 5) :  argument three matches multiple formal arguments                            You can bank check the packet in which a role is defined using the                environs()                function:
The result should include                namespace:purrr                if                map()                is coming from the purrr package. To explicitly reference the package to get a role from, apply the colon operator                ::. For example,
For loops
Exercise 21.2.1
Write for-loops to:
- Compute the hateful of every column in                    mtcars.
- Make up one's mind the type of each column in                    nycflights13::flights.
- Compute the number of unique values in each column of                    iris.
- Generate 10 random normals for each of \(\mu\) = -10, 0, 10, and 100.
The answers for each part are beneath.
-                     To compute the mean of every column in mtcars.
-                     Determine the blazon of each column in nycflights13::flights.I used a list, not a character vector, since the class of an object can have multiple values. For example, the class of thetime_hourcolumn is POSIXct, POSIXt.
-                     To compute the number of unique values in each column of the irisdataset.
-                     To generate 10 random normals for each of \(\mu\) = -10, 0, 10, and 100. Even so, we don't need a for loop for this since rnorm()recycle thehatefulargument.matrix(rnorm(due north * length(mu), mean = mu), ncol = n) #> [,1] [,2] [,iii] [,4] [,five] [,half dozen] [,7] [,8] [,9] [,10] #> [1,] -ix.930 -ix.56 -nine.88 -ten.2061 -12.27 -8.926 -eleven.178 -9.51 -eight.663 -ix.39 #> [2,] -0.639 2.76 -1.91 0.0192 2.68 -0.665 -0.976 -1.70 0.237 -0.11 #> [3,] 9.950 10.05 10.86 10.0296 ix.64 11.114 11.065 8.53 eleven.318 x.17 #> [four,] 99.749 100.58 99.76 100.5498 100.21 99.754 100.132 100.28 100.524 99.91
Exercise 21.2.two
Eliminate the for loop in each of the following examples past taking advantage of an existing function that works with vectors:
Since                  str_c()                  already works with vectors, use                  str_c()                  with the                  collapse                  argument to return a unmarried string.
For this I'm going to rename the variable                  sd                  to something different because                  sd                  is the name of the function we want to use.
We could simply employ the                  sd                  role.
Or if there was a need to utilise the equation (e.g. for pedagogical reasons), and then the functions                  mean()                  and                  sum()                  already work with vectors:
The code higher up is calculating a cumulative sum. Utilise the function                  cumsum()                
Exercise 21.2.three
Combine your function writing and for loop skills:
-                     Write a for loop that prints()the lyrics to the children's song "Alice the camel".
-                     Convert the nursery rhyme "ten in the bed" to a part. Generalize it to whatsoever number of people in any sleeping structure. 
-                     Convert the vocal "99 bottles of beer on the wall" to a function. Generalize to any number of any vessel containing any liquid on surface. 
The answers to each part follow.
-                     The lyrics for Alice the Camel are: Alice the camel has five humps. 
 Alice the camel has five humps.
 Alice the camel has v humps.
 Then go, Alice, go.This poetry is repeated, each time with one fewer hump, until there are no humps. The last poetry, with no humps, is: Alice the camel has no humps. 
 Alice the camel has no humps.
 Alice the camel has no humps.
 At present Alice is a horse.Nosotros'll iterate from five to no humps, and print out a dissimilar last line if there are no humps. humps <- c("five", "four", "three", "two", "one", "no") for (i in humps) { cat(str_c("Alice the camel has ", rep(i, 3), " humps.", collapse = " \north " ), " \due north ") if (i == "no") { true cat("Now Alice is a horse. \northward ") } else { cat("And then become, Alice, get. \n ") } cat(" \n ") } #> Alice the camel has v humps. #> Alice the camel has five humps. #> Alice the camel has 5 humps. #> So go, Alice, go. #> #> Alice the camel has four humps. #> Alice the camel has iv humps. #> Alice the camel has four humps. #> So go, Alice, become. #> #> Alice the camel has three humps. #> Alice the camel has three humps. #> Alice the camel has three humps. #> Then go, Alice, go. #> #> Alice the camel has two humps. #> Alice the camel has ii humps. #> Alice the camel has two humps. #> Then get, Alice, become. #> #> Alice the camel has i humps. #> Alice the camel has one humps. #> Alice the camel has i humps. #> So go, Alice, go. #> #> Alice the camel has no humps. #> Alice the camel has no humps. #> Alice the camel has no humps. #> Now Alice is a horse.
-                     The lyrics for X in the Bed are: Here we go! 
 There were ten in the bed
 and the picayune one said,
 "Roll over, roll over."
 So they all rolled over and i barbarous out.This poetry is repeated, each fourth dimension with one fewer in the bed, until there is ane left. That last verse is: 1! There was one in the bed 
 and the little one said,
 "I'm lonely…"numbers <- c( "x", "nine", "8", "seven", "six", "five", "four", "iii", "two", "one" ) for (i in numbers) { cat(str_c("There were ", i, " in the bed \north ")) cat("and the little 1 said \northward ") if (i == "one") { cat("I'm lonely...") } else { true cat("Coil over, roll over \n ") cat("So they all rolled over and ane savage out. \n ") } cat(" \n ") } #> There were ten in the bed #> and the little ane said #> Gyre over, roll over #> Then they all rolled over and one fell out. #> #> There were ix in the bed #> and the little 1 said #> Roll over, scroll over #> So they all rolled over and ane fell out. #> #> There were eight in the bed #> and the little one said #> Roll over, roll over #> So they all rolled over and one fell out. #> #> There were seven in the bed #> and the little i said #> Curlicue over, roll over #> So they all rolled over and one fell out. #> #> There were six in the bed #> and the little ane said #> Roll over, gyre over #> So they all rolled over and one vicious out. #> #> There were five in the bed #> and the little 1 said #> Roll over, whorl over #> So they all rolled over and one fell out. #> #> In that location were four in the bed #> and the little ane said #> Roll over, gyre over #> And so they all rolled over and one savage out. #> #> There were three in the bed #> and the petty i said #> Roll over, gyre over #> So they all rolled over and one barbarous out. #> #> At that place were two in the bed #> and the little 1 said #> Whorl over, scroll over #> So they all rolled over and one fell out. #> #> There were i in the bed #> and the little one said #> I'm lone...
-                     The lyrics of Ninety-9 Bottles of Beer on the Wall are 99 bottles of beer on the wall, 99 bottles of beer. 
 Take one down, pass information technology around, 98 bottles of beer on the wallThis verse is repeated, each time with one few canteen, until there are no more bottles of beer. The last poetry is No more bottles of beer on the wall, no more bottles of beer. 
 We've taken them down and passed them around; now nosotros're drunk and passed out!For the bottles of beer, I define a helper function to correctly print the number of bottles. bottles <- function(due north) { if (north > i) { str_c(due north, " bottles") } else if (n == 1) { "1 bottle" } else { "no more bottles" } } beer_bottles <- role(total_bottles) { # print each lyric for (current_bottles in seq(total_bottles, 0)) { # commencement line cat(str_to_sentence(str_c(bottles(current_bottles), " of beer on the wall, ", bottles(current_bottles), " of beer. \n "))) # second line if (current_bottles > 0) { cat(str_c( "Have 1 down and laissez passer it around, ", bottles(current_bottles - 1), " of beer on the wall. \n " )) } else { cat(str_c("Go to the store and buy some more than, ", bottles(total_bottles), " of beer on the wall. \n ")) } cat(" \north ") } } beer_bottles(iii) #> 3 Bottles of beer on the wall, 3 bottles of beer. #> Take 1 downwardly and pass information technology effectually, 2 bottles of beer on the wall. #> #> 2 Bottles of beer on the wall, two bottles of beer. #> Have 1 down and laissez passer it around, 1 canteen of beer on the wall. #> #> 1 Bottle of beer on the wall, one bottle of beer. #> Take one down and pass it effectually, no more bottles of beer on the wall. #> #> No more bottles of beer on the wall, no more than bottles of beer. #> Go to the store and buy some more, 3 bottles of beer on the wall.
Practice 21.two.iv
It's common to see for loops that don't preallocate the output and instead increase the length of a vector at each footstep:
How does this touch on functioning? Design and execute an experiment.
In order to compare these two approaches, I'll define ii functions:                    add_to_vector                    volition append to a vector, like the case in the question, and                    add_to_vector_2                    which pre-allocates a vector.
I'll use the package microbenchmark to run these functions several times and compare the time information technology takes. The package microbenchmark contains utilities for benchmarking R expressions. In detail, the                    microbenchmark()                    role will run an R expression a number of times and time information technology.
In this example, appending to a vector takes 325 times longer than pre-allocating the vector. Yous may get dissimilar answers, only the longer the vector and the larger the objects, the more that pre-allocation volition outperform appending.
For loop variations
Exercise 21.3.ane
Imagine you have a directory full of CSV files that you want to read in. You have their paths in a vector,                files <- dir("data/", pattern = "\\.csv$", full.names = True), and now desire to read each one with                read_csv(). Write the for loop that will load them into a single data frame.
Since, the number of files is known, pre-allocate a list with a length equal to the number of files.
So, read each file into a data frame, and assign it to an element in that listing. The result is a list of information frames.
Finally, utilise use                  bind_rows()                  to combine the list of data frames into a single data frame.
Alternatively, I could take pre-allocated a list with the names of the files.
Exercise 21.iii.2
What happens if you use                for (nm in names(x))                and                x                has no names? What if only some of the elements are named? What if the names are not unique?
Let'south try it out and see what happens. When in that location are no names for the vector, information technology does non run the code in the loop. In other words, it runs zero iterations of the loop.
Notation that the length of                  Cipher                  is zero:
If there just some names, and so we get an error for trying to access an element without a proper noun.
Finally, if the vector contains duplicate names, then                  x[[nm]]                  returns the                  showtime                  element with that name.
Exercise 21.3.3
Write a function that prints the hateful of each numeric column in a information frame, along with its name. For instance,                  show_mean(iris)                  would print:
Extra claiming: what part did I use to make sure that the numbers lined up nicely, even though the variable names had unlike lengths?
At that place may be other functions to do this, but I'll use                  str_pad(), and                  str_length()                  to ensure that the space given to the variable names is the same. I messed around with the options to                  format()                  until I got two digits.
Exercise 21.3.4
What does this code do? How does it work?
This code mutates the                  disp                  and                  am                  columns:
-                     dispis multiplied by 0.0163871
-                     amis replaced by a factor variable.
The code works by looping over a named list of functions. Information technology calls the named part in the list on the column of                  mtcars                  with the same proper name, and replaces the values of that column.
This is a function.
This applies the function to the cavalcade of                  mtcars                  with the same name
For loops vs. functionals
Do 21.4.ane
Read the documentation for                apply(). In the 2nd case, what two for-loops does it generalize.
For an object with ii-dimensions, such as a matrix or information frame,                  use()                  replaces looping over the rows or columns of a matrix or data-frame. The                  apply()                  function is used like                  apply(X, MARGIN, FUN, ...), where                  X                  is a matrix or array,                  FUN                  is a part to employ, and                  ...                  are additional arguments passed to                  FUN.
When                  MARGIN = 1, then the function is applied to each row. For example, the following instance calculates the row ways of a matrix.
That is equivalent to this for-loop.
When                  MARGIN = ii,                  apply()                  is equivalent to a for-loop looping over columns.
Exercise 21.4.two
Adapt                col_summary()                and then that it only applies to numeric columns. You lot might want to start with an                is_numeric()                function that returns a logical vector that has a                Truthful                corresponding to each numeric column.
The original                  col_summary()                  function is
The adapted version adds actress logic to just apply the office to numeric columns.
Allow's examination that                  col_summary2()                  works by creating a small data frame with some numeric and non-numeric columns.
                    df <-                                            tibble(                       X1 =                      c(i,                      2,                      3),                       X2 =                      c("A",                      "B",                      "C"),                       X3 =                      c(0,                      -1,                      five),                       X4 =                      c(TRUE,                      FALSE,                      TRUE) )                      col_summary2(df, mean)                      #>   X1   X3                                            #> 2.00 i.33                                                      As expected, it only calculates the mean of the numeric columns,                  X1                  and                  X3. Permit's test that information technology works with another function.
The map functions
Exercise 21.five.1
Write lawmaking that uses one of the map functions to:
- Compute the mean of every column in                    mtcars.
- Decide the type of each column in                    nycflights13::flights.
- Compute the number of unique values in each column of                    iris.
- Generate 10 random normals for each of \(\mu = -10\), \(0\), \(10\), and \(100\).
-                     To calculate the hateful of every cavalcade in mtcars, utilize the rolemean()to each column, and usemap_dbl, since the results are numeric.
-                     To calculate the type of every cavalcade in nycflights13::flightsutilize the functiontypeof(), discussed in the department on Vector basics, and usemap_chr(), since the results are grapheme.
-                     The function n_distinct()calculates the number of unique values in a vector.The map_int()office is used sincelength()returns an integer. Notwithstanding, themap_dbl()function will too piece of work.An alternative to the n_distinct()function is the expression,length(unique(...)). Then_distinct()function is more curtailed and faster, simplylength(unique(...))provides an example of using anonymous functions with map functions. An anonymous part tin be written using the standard R syntax for a function:Additionally, map functions accept 1-sided formulas every bit a more concise culling to specify an anonymous role: In this case, the anonymous function accepts one argument, which is referenced past .10in the expressionlength(unique(.x)).
-                     To generate ten random normals for each of \(\mu = -10\), \(0\), \(x\), and \(100\): The result is a listing of numeric vectors. Since a single call of rnorm()returns a numeric vector with a length greater than one we cannot applymap_dbl, which requires the function to render a numeric vector that is but length one (see Exercise 21.5.4). The map functions pass any additional arguments to the office existence called.
Exercise 21.5.ii
How tin you lot create a single vector that for each cavalcade in a data frame indicates whether or not it's a factor?
The function                  is.factor()                  indicates whether a vector is a cistron.
Checking all columns in a data frame is a job for a                  map_*()                  function. Since the result of                  is.cistron()                  is logical, nosotros will use                  map_lgl()                  to apply                  is.factor()                  to the columns of the data frame.
Do 21.5.3
What happens when you utilize the map functions on vectors that aren't lists? What does                map(1:5, runif)                do? Why?
Map functions work with any vectors, non only lists. Equally with lists, the map functions will use the function to each element of the vector. In the following examples, the inputs to                  map()                  are diminutive vectors (logical, character, integer, double).
                                          map(c(TRUE,                      FALSE,                      TRUE),                      ~                                                                  !.)                      #> [[1]]                      #> [one] Simulated                      #>                                            #> [[two]]                      #> [ane] TRUE                      #>                                            #> [[3]]                      #> [1] Simulated                      map(c("Hello",                      "World"), str_to_upper)                      #> [[1]]                      #> [1] "Hello"                      #>                                            #> [[2]]                      #> [1] "World"                      map(1                      :                      v,                      ~                                                                  rnorm(.))                      #> [[one]]                      #> [ane] 1.42                      #>                                            #> [[ii]]                      #> [1] -0.384 -0.174                      #>                                            #> [[3]]                      #> [1] -0.222 -1.010  0.481                      #>                                            #> [[4]]                      #> [1]  one.604 -1.515 -one.416  0.877                      #>                                            #> [[5]]                      #> [1]  0.624  two.112 -0.356 -1.064  i.077                      map(c(-                      0.5,                      0,                      1),                      ~                                                                  rnorm(1,                      hateful =                      .))                      #> [[ane]]                      #> [ane] 0.682                      #>                                            #> [[two]]                      #> [1] 0.198                      #>                                            #> [[3]]                      #> [1] 0.6                                                      It is important to exist aware that while the input of                  map()                  can be whatever vector, the output is always a list.
This expression is equivalent to running the following.
The                  map()                  function loops through the numbers 1 to 5. For each value, it calls the                  runif()                  with that number every bit the start argument, which is the number of sample to draw. The upshot is a length five list with numeric vectors of sizes i through five, each with random samples from a compatible distribution. Notation that although input to                  map()                  was an integer vector, the render value was a list.
Exercise 21.5.4
What does                  map(-2:2, rnorm, n = five)                  do? Why?
What does                  map_dbl(-2:two, rnorm, n = 5)                  practice? Why?
Consider the first expression.
This expression takes samples of size five from five normal distributions, with means of (-2, -1, 0, i, and two), merely the aforementioned standard difference (i). It returns a list with each chemical element a numeric vectors of length 5.
However, if instead, we apply                  map_dbl(), the expression raises an fault.
This is because the                  map_dbl()                  function requires the part information technology applies to each element to return a numeric vector of length one. If the office returns either a non-numeric vector or a numeric vector with a length greater than one,                  map_dbl()                  will raise an error. The reason for this strictness is that                  map_dbl()                  guarantees that information technology will render a numeric vector of the                  aforementioned length                  equally its input vector.
This concept applies to the other                  map_*()                  functions. The function                  map_chr()                  requires that the function always render a                  grapheme                  vector of length one;                  map_int()                  requires that the function always render an                  integer                  vector of length one;                  map_lgl()                  requires that the function ever return an                  logical                  vector of length one. Apply the                  map()                  function if the function will render values of varying types or lengths.
To return a numeric vector, use                  flatten_dbl()                  to coerce the listing returned by                  map()                  to a numeric vector.
Do 21.5.5
Rewrite                map(x, function(df) lm(mpg ~ wt, data = df))                to eliminate the anonymous role.
This code in this question does not run, so I will use the following lawmaking.
We can eliminate the use of an anonymous role using the                  ~                  shortcut.
Though not the intent of this question, the other style to eliminate anonymous function is to create a named one.
Dealing with failure
Mapping over multiple arguments
Walk
Other patterns of for loops
Exercise 21.ix.1
Implement your own version of                every()                using a for loop. Compare it with                purrr::every(). What does purrr's version practice that your version doesn't?
The part                  purrr::every()                  does fancy things with the predicate function argument                  .p, like taking a logical vector instead of a function, or being able to test part of a cord if the elements of                  .x                  are lists.
Practise 21.9.two
Create an enhanced                col_summary()                that applies a summary function to every numeric column in a data frame.
I will use                  map                  to apply the function to all the columns, and                  keep                  to but select numeric columns.
Exercise 21.9.3
A possible base R equivalent of                  col_summary()                  is:
But it has a number of bugs as illustrated with the post-obit inputs:
What causes these bugs?
The cause of these bugs is the beliefs of                  sapply(). The                  sapply()                  function does not guarantee the type of vector it returns, and volition returns dissimilar types of vectors depending on its inputs. If no columns are selected, instead of returning an empty numeric vector, information technology returns an empty list. This causes an error since nosotros can't use a list with                  [.
The                  sapply()                  function tries to exist helpful by simplifying the results, just this beliefs tin can be counterproductive. It is okay to use the                  sapply()                  part interactively, only avert programming with it.
Source: https://jrnold.github.io/r4ds-exercise-solutions/iteration.html
0 Response to "Reading Each Row in List for for Loop"
Postar um comentário