class: center, middle, inverse, title-slide # tips to tame youR dRagon ## Hannah L. Owens ###
@HannahOish
### 2021-06-14 --- <style type="text/css"> .remark-slide-content { font-size: 30px; padding: 1em 4em 1em 4em; } </style> # Does your code have you tangled up in knots? <div align="center"> <img src="https://ehillus.files.wordpress.com/2014/10/tangled-dragon.jpg" height=400> </div> --- # Tip 1: Take a deep breath. .pull-left[ * When you have a problem with a complicated piece of code, take a minute to focus and clear your mind. ] .pull-right[ <img src="https://techsupport.foreverwarm.com/wp-content/uploads/2011/03/frustrated-computer-guy.png" width=300> ] --- # Tip 2: Start with a clean slate. .pull-left[ * Open a new script document. * Clear you environment. ```r rm(list=ls()) ``` ] .pull-right[ <img src="https://www.bigimmigrationlawblog.com/wp-content/uploads/sites/365/2020/11/iStock-1023471968-330x248.jpg" width=300> ] --- # Tip 3: Be patient .pull-left[ * Go through the code *one* line at a time. * Highlight, then hit "Control" + "Enter" or "Command" + "Return" ] .pull-right[ <img src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Enter-key.jpg" width=300> ] --- # Tip 4: Keep your lines short .pull-left[ * No one has ever won an award for shortest R code (that I know of) * Make a series of simple statements. ] .pull-right[ ```r # Good a <- "one" b <- "two" d <- "three" test <- c(a,b,d) print(test) #Bad print(paste(c(a="one", b="two", d="three"))) ``` ] --- # Tip 5: Comment early, Comment often .pull-left[ * Use them for metadata * Explain code chunks * Keep them brief * Keep them relevant * Keep it constructive * Can be used to debug * OK, maybe don't use them ALLLL the time ] .pull-right[ <img src="https://img.devrant.com/devrant/rant/c_662893_Sw1f4.jpg" height=400> ] --- # Tip 6: Use print() to show exactly what is happening and when .pull-left[ ```r testFunction <- function(y){ if (y %% 2==0){ return("notOdd") } else return() } x <- c() for(i in 1:3){ print(i) print("executing function") newI <- testFunction(i) print(paste("newI: ", newI)) print("appending new i") x <- c(x,newI) print(x) } ``` ] .pull-right[ ``` ## [1] 1 ## [1] "executing function" ## [1] "newI: " ## [1] "appending new i" ## NULL ## [1] 2 ## [1] "executing function" ## [1] "newI: notOdd" ## [1] "appending new i" ## [1] "notOdd" ## [1] 3 ## [1] "executing function" ## [1] "newI: " ## [1] "appending new i" ## [1] "notOdd" ``` ] --- # Tip 7: Use unique indexes for every loop .pull-left[ * Do not use `i` as a universal index * If you don't change the index for every loop, you could accidentally recycle something * Also it will turn nested loops into a hot mess in no time flat. ] .pull-right[ <img src="https://live.staticflickr.com/7229/7162673224_d417dce68a_z.jpg" height=400> ] --- # Tip 8: Break out of the loop! .pull-left[ * Turn your loops into functions * Functions are easier to debug * Functions are faster ] .pull-right[ <img src="https://freshstitches.com/wp-content/uploads/2012/11/cut-loop-stitch-1024x768.jpg" height=400> ] --- # Tip 9: If you *have* to loop, make sure your code works first .pull-left[ * Go through it line by line * Be patient ] .pull-right[ <img src="https://i.insider.com/5b76eda93cccd123008b45d1?width=1000&format=jpeg&auto=webp" height=400> ] --- # Tip 10: Simplify your piping operations .pull-left[ * Start with basic steps * Run lines line by line ] .pull-right[ ```r library(magrittr) a <- seq(1,10, by = 2) # Good a %>% log() %>% diff() %>% exp() %>% round(1) # Bad a %>% log() %>% diff() %>% exp() %>% round(1) ``` ] --- # Tip 11: Try .pull-left[ * You may have to loop over messy data * try() allows the loop to keep going instead of stalling * Skips over problem and produces error message ] .pull-right[ ```r inputs <- list(1, 2, 4, -5, 'oops', 0, 10) # With try for(input in inputs) { try(print(paste("log of", input, "=", log(input)))) } ``` ``` ## [1] "log of 1 = 0" ## [1] "log of 2 = 0.693147180559945" ## [1] "log of 4 = 1.38629436111989" ``` ``` ## Warning in log(input): NaNs produced ``` ``` ## [1] "log of -5 = NaN" ## Error in log(input) : non-numeric argument to mathematical function ## [1] "log of 0 = -Inf" ## [1] "log of 10 = 2.30258509299405" ``` ] --- # Tip 12: tryCatch .pull-left[ * "Fancy" version of try * You can produce custom errors and warnings that are more informative * Wrap in a function for maximum effect ] .pull-right[ ```r robustLog = function(x) { tryCatch(log(x), warning = function(w) {print(paste("negative argument", x)) log(-x)}, error = function(e) {print(paste("non-numeric argument", x)) NaN}) } for(input in inputs) { print(paste("robust log of", input, "=", robustLog(input))) } ``` ``` ## [1] "robust log of 1 = 0" ## [1] "robust log of 2 = 0.693147180559945" ## [1] "robust log of 4 = 1.38629436111989" ## [1] "negative argument -5" ## [1] "robust log of -5 = 1.6094379124341" ## [1] "non-numeric argument oops" ## [1] "robust log of oops = NaN" ## [1] "robust log of 0 = -Inf" ## [1] "robust log of 10 = 2.30258509299405" ``` ] --- .left-column[ # Fin. ] .right-column[ <img src="https://pyxis.nymag.com/v1/imgs/76a/792/ca8c6ae202df791dcd06c700e9650882f9-19-how-to-train-dragon.rhorizontal.w700.jpg"> ]