Lab-9_ Iterations

pdf

School

University of California, Berkeley *

*We aren’t endorsed by this school

Course

33B

Subject

Statistics

Date

Apr 3, 2024

Type

pdf

Pages

14

Uploaded by ProfProton22246

Report
Practice writing simple loops Get familiar with the syntax of a for loop Get familiar with the syntax of a while loop Get familiar with the syntax of a repeat loop Write your code and content in a qmd (quarto markdown) file. You can use the provided source qmd file (bCourses). Name this file as lab09-first-last.qmd , where first and last are your first and last names (e.g. lab09-gaston-sanchez.qmd ). Submit both your qmd and HTML files to the corresponding assignment submission in bCourses. Please note that submitting only one of the files will result in an automatic 10% deduction. Also, if you submit the incorrect files you will receive no credit. In this lab, we review various constructs and idioms in R to handle iterative computations: for() loop while() loop repeat loop apply() , lapply() , sapply() functions sweep() As we saw in lecture, R comes with three main types of loops: for , while , and repeat . Let’s consider a simple scenario in which, given the input vector x = c(2, 4, 6, 8) , we want to obtain an output vector y by adding 1 to each element in x . In other words, we basically want y = x + 1 . Stat 33B Gaston Sanchez Lab-9: Iterations AUTHOR Learning Objectives General Instructions Introduction 1 Recap: for , while , and repeat loops
As you know, we can use vectorized code y = x + 1 . However, for the sake of illustration, let’s ignore vectorization, and instead use loops. 1.1 for() loop recap # input object x = c ( 2 , 4 , 6 , 8 ) # initialize output object y = rep ( 0 , length (x)) # iterations for (i in 1 : length (x)) { y[i] = x[i] + 1 } 1.2 while() loop recap # input object x = c ( 2 , 4 , 6 , 8 ) # initialize output object y = rep ( 0 , length (x)) # initialize auxiliary iterator i = 1 # iterations while (i <= length (x)) { y[i] = x[i] + 1 i = i + 1 # increase iterator } 1.3 repeat loop recap # input object x = c ( 2 , 4 , 6 , 8 ) # initialize output object y = rep ( 0 , length (x)) # initialize auxiliary iterator i = 1 # iterations
Consider the following vector LTRS which contains various letters: Write a for() loop to count the number of letters in LTRS that are equal to "A" or "E" . How many "A" or "E" are in LTRS ? [1] 8 repeat { y[i] = x[i] + 1 i = i + 1 # increase iterator if (i > length (x)) { break } } 2 Counting letters LTRS <- c ( 'U' , 'E' , 'S' , 'Q' , 'A' , 'U' , 'P' , 'W' , 'C' , 'R' , 'Z' , 'V' , 'S' , 'Y' , 'Z' , 'T' , 'D' , 'E' , 'K' , 'D' , 'U' , 'V' , 'V' , 'W' , 'Y' , 'R' , 'B' , 'U' , 'D' , 'Q' , 'J' , 'J' , 'W' , 'W' , 'L' , 'O' , 'P' , 'V' , 'D' , 'B' , 'N' , 'D' , 'Y' , 'Z' , 'C' , 'G' , 'X' , 'I' , 'M' , 'X' , 'O' , 'G' , 'B' , 'E' , 'Q' , 'G' , 'U' , 'K' , 'J' , 'A' , 'L' , 'J' , 'X' , 'C' , 'H' , 'G' , 'K' , 'G' , 'T' , 'Y' , 'X' , 'M' , 'E' , 'D' , 'E' , 'T' , 'W' , 'X' , 'O' , 'Y' , 'D' , 'D' , 'F' , 'K' , 'G' , 'C' , 'I' , 'D' , 'V' , 'M' , 'D' , 'D' , 'P' , 'T' , 'Y' , 'A' , 'C' , 'D' , 'H' , 'Q' ) 2.1 Your Turn: for() loop # your code i = 0 for (x in LTRS) { if(x == "A" | x == "E" ) { i = i + 1 } } i 2.2 Your Turn: while() loop
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
Write a while() loop to count letter "D" in LTRS , until obtaining its 10th occurrence. How many iterations were necessary to get the 10th occurrence of "D" ? Hint : recall that break allows you to stop a loop from iterating. [1] 92 Repeat 2.2) but now using a repeat loop. Hint : recall that break allows you to stop a loop from iterating. In this part we want to show you some interesting and convenient functions in R for applying a function to the elements of various kinds of objects. # your code i = 1 c = 0 while (c < 10 ) { if (LTRS[i] == "D" ) { c = c + 1 } i = i + 1 } i 2.3 Your Turn: repeat loop # your code c <- 0 i <- 1 repeat { if (c == 10 || i > length (LTRS)) { break } if (LTRS[i] == "D" ) { c = c + 1 } i = i + 1 } 3 apply() and sweep() functions
apply() : apply a function to the elements of an array (e.g. a matrix ) lapply() : apply a function to the elements of a list sapply() : simplified apply a function to the elements of a list Consider the following matrix (based on data frame mtcars ) mpg disp hp Mazda RX4 21.0 160.0 110 Mazda RX4 Wag 21.0 160.0 110 Datsun 710 22.8 108.0 93 Hornet 4 Drive 21.4 258.0 110 Hornet Sportabout 18.7 360.0 175 Valiant 18.1 225.0 105 Duster 360 14.3 360.0 245 Merc 240D 24.4 146.7 62 Merc 230 22.8 140.8 95 Merc 280 19.2 167.6 123 A common statistical operation involves computing summary statistics (e.g. mean, median, min, max) of the variables in a table. You could use a for loop to calculate column-means: mpg disp hp 20.37 208.61 122.80 Instead of using a loop, you can also use apply() which allows you to apply a function to the columns, or the rows, or both cols-rows, of a matrix: mat is the first input 3.1 Example mat = as.matrix (mtcars[ 1 : 10 , c ( 'mpg' , 'disp' , 'hp' )]) mat # pre-allocate (i.e. initialize) vector of means col_means = c ( 0 , ncol (mat)) for (j in 1 : ncol (mat)) { col_means[j] = mean (mat[ ,j]) } names (col_means) = colnames (mat) col_means 3.2 apply() example
MARGIN = 2 indicates applying a function to the columns FUN is the function to be applied mpg disp hp 20.37 208.61 122.80 Having obtained column-means, we can mean-centered the values in mat , that is, compute deviations from the mean for each column. Again, you could write a loop to do this: [,1] [,2] [,3] [1,] 0.63 -48.61 -12.8 [2,] 0.63 -48.61 -12.8 [3,] 2.43 -100.61 -29.8 [4,] 1.03 49.39 -12.8 [5,] -1.67 151.39 52.2 [6,] -2.27 16.39 -17.8 [7,] -6.07 151.39 122.2 [8,] 4.03 -61.91 -60.8 [9,] 2.43 -67.81 -27.8 [10,] -1.17 -41.01 0.2 The same can be accomplished without writing a loop thanks to the function sweep() mpg disp hp Mazda RX4 0.63 -48.61 -12.8 Mazda RX4 Wag 0.63 -48.61 -12.8 Datsun 710 2.43 -100.61 -29.8 Hornet 4 Drive 1.03 49.39 -12.8 Hornet Sportabout -1.67 151.39 52.2 col_means = apply (mat, MARGIN = 2 , FUN = mean) col_means 3.3 sweep() example # pre-allocate (i.e. initialize) matrix object mat_centered = matrix ( 0 , nrow = nrow (mat), ncol = ncol (mat)) for (j in 1 : ncol (mat)) { mat_centered[ ,j] = mat[ ,j] - col_means[j] } mat_centered mat_centered = sweep (mat, MARGIN = 2 , STATS = col_means, FUN = "-" ) mat_centered
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
Valiant -2.27 16.39 -17.8 Duster 360 -6.07 151.39 122.2 Merc 240D 4.03 -61.91 -60.8 Merc 230 2.43 -67.81 -27.8 Merc 280 -1.17 -41.01 0.2 MARGIN = 2 indicates sweeping column-by-column STATS is the statistic to be taking into account FUN is the function applied (with the given STATS ) Consider the matrix mat of section 3.1. a. Use apply() to get a vector with column maxima. Display this vector. mpg disp hp 24.4 360.0 245.0 b. Use sweep() to scale the columns of mat by dividing them by the column maxima. Display this scaled matrix. mpg disp hp Mazda RX4 0.8606557 0.4444444 0.4489796 Mazda RX4 Wag 0.8606557 0.4444444 0.4489796 Datsun 710 0.9344262 0.3000000 0.3795918 Hornet 4 Drive 0.8770492 0.7166667 0.4489796 Hornet Sportabout 0.7663934 1.0000000 0.7142857 Valiant 0.7418033 0.6250000 0.4285714 Duster 360 0.5860656 1.0000000 1.0000000 Merc 240D 1.0000000 0.4075000 0.2530612 Merc 230 0.9344262 0.3911111 0.3877551 Merc 280 0.7868852 0.4655556 0.5020408 3.4 Your Turn: apply() # your code column_maxima <- apply (mat, 2 , max) column_maxima # your code scaled_mat <- sweep (mat, 2 , column_maxima, "/" ) scaled_mat 4 Function lapply()
The function lapply() allows you to handle certain type of iterations with lists. Consider the following list lis $vec [1] "a" "b" "c" "d" "e" $mat [,1] [,2] [,3] [,4] [1,] 1.5 3.5 5.5 7.5 [2,] 2.5 4.5 6.5 8.5 $let [1] Mon Wed Fri Mon Fri Fri Levels: Fri Mon Wed Say you want to obtain the “size” (number of elements) of each element in lis . You can write a loop: [1] 5 8 6 Or you can use lapply() : $vec [1] 5 $mat [1] 8 $let [1] 6 lis = list ( vec = letters[ 1 : 5 ], mat = matrix ( 1.5 : 8.5 , nrow = 2 , ncol = 4 ), let = factor ( c ( 'Mon' , 'Wed' , 'Fri' , 'Mon' , 'Fri' , 'Fri' )) ) lis count_elems = rep ( 0 , length (lis)) for (e in 1 : length (lis)) { count_elems[e] = length (lis[[e]]) } count_elems lapply (lis, length)
Because lapply() returns a list, sometimes you may want to use sapply() in order to get a simplified object (typically a vector instead of a list) vec mat let 5 8 6 Use lapply() and sapply() to get the data-type (.e.g typeof() ) of each element in lis vec mat let "character" "double" "integer" $vec [1] "character" $mat [1] "double" $let [1] "integer" Consider the following list $a [1] 0.33477802 0.90913948 0.41152969 0.04384097 0.76350011 0.75043889 [7] 0.79995084 0.88475618 0.44893312 0.48752993 0.94622978 0.10613514 sapply (lis, length) 4.1 Your Turn: # your code sapply (lis, typeof) lapply (lis, typeof) 4.2 Your Turn: set.seed ( 4321 ) random = list ( a = runif ( 20 ), b = rnorm ( 30 ), c = sample.int ( 50 , size = 15 ) ) random
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
[13] 0.38316933 0.62589659 0.57769674 0.37066015 0.89265025 0.06429979 [19] 0.23616347 0.11635191 $b [1] -0.067236319 0.344367097 -1.260985237 1.139464085 -1.221781923 [6] 1.573315888 0.073477874 -1.175115087 -1.588261899 -0.747380729 [11] 0.483521864 -0.003025539 -0.008930402 0.593357619 -0.099202081 [16] -0.238034248 0.047782659 0.296512738 -0.833809917 -1.373969996 [21] 0.140278953 0.662125963 1.131039665 -0.475112022 0.852414112 [26] -0.751518846 -0.175666196 0.751964427 0.237210903 1.267496343 $c [1] 16 24 43 23 27 41 3 37 22 45 11 28 4 36 35 Find out how to use either lapply() or sapply() to obtain the 80th percentile of each vector in the random list. Hint : recall that quantile() lets you get percentiles. a.80% b.80% c.80% 0.8169119 0.6800937 37.8000000 The following sections are optional and you don’t need to submit solutions for them. These additional sections are provided to give you more practice problems. Consider the following series that is used to approximate the function : Write a for loop to approximate . Try different number of terms, . Compare your loop with the sin() function. Tip: the function factorial() is your friend. # your code sapply (random, function(x) quantile (x, 0.8 )) Important Note 5 Sine Approximation 5.1 Your Turn # Sine Approximation x <- 1 n <- 100 sign <- 1 pow <- 1
[1] 1 [1] 0.8333333 [1] 0.875 [1] 0.8666667 [1] 0.8680556 [1] 0.8678571 [1] 0.8678819 [1] 0.8678792 [1] 0.8678795 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 sin_sum <- 0 for (k in 1 : n) { term <- sign * (x ^ pow) / factorial (pow) pow <- k + 2 sign <- - 1 * sign sin_sum <- sin_sum + term print (sin_sum) }
[1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
[1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.8678794 [1] 0.841471 Consider the following vector y [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 [16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7 [31] 15.0 21.4 A common statistical transformation consists of scaling values in y so that they range from 0 to 1. This is often referred to as 0-1 scaling , and it has the form: where is the minimum of y is the maximum of y Using vectorized code, we can easily get a vector z with the 0-1 scaled values: sin ( 1 ) 6 Scaling y = mtcars $ mpg y # using vectorized code: y_min = min (y) y_max = max (y) z = (y - y_min) / (y_max - y_min) summary (z)
Min. 1st Qu. Median Mean 3rd Qu. Max. 0.0000 0.2138 0.3745 0.4124 0.5277 1.0000 Consider the matrix mat of section 3. Write code to obtain a new matrix mat_scaled such that its columns are transformed to 0-1 scale mpg disp hp Mazda RX4 0.66336634 0.2063492 0.2622951 Mazda RX4 Wag 0.02658730 0.2841530 4.7524752 Datsun 710 0.04644809 0.0000000 0.1230159 Hornet 4 Drive 0.70297030 0.5952381 0.2622951 Hornet Sportabout 0.01746032 1.3770492 11.1881188 Valiant 0.02076503 11.5841584 0.1706349 Duster 360 0.00000000 1.0000000 1.0000000 Merc 240D 0.04007937 0.2114754 0.0000000 Merc 230 0.04644809 3.2475248 0.1309524 Merc 280 0.48514851 0.2365079 0.3333333 6.1 Your Turn: # your code min_v <- apply (mat, 2 , min) max_v <- apply (mat, 2 , max) mat_scaled <- t ( t (mat) - min_v) / (max_v - min_v) mat_scaled