---
title: "Orienting to Quarto for IAML"
author: "TA Lab Key"
date: "`r lubridate::today()`"
format: 
  html: 
    embed-resources: true
    toc: true 
    toc_depth: 4
editor_options: 
  chunk_output_type: console
---

```{r}
options(conflicts.policy = "depends.ok") # deals with package conflicts
devtools::source_url("https://github.com/jjcurtin/lab_support/blob/main/fun_ml.R?raw=true") # source functions
tidymodels_conflictRules() # deals with package conflicts

library(tidyverse) 
library(tidymodels)

options(tibble.width = Inf, tibble.print_max = Inf)
theme_set(theme_classic()) 

data <- modeldata::ames |> janitor::clean_names() |> select(1:20, sale_price)

devtools::source_url("https://github.com/jjcurtin/lab_support/blob/main/fun_plots.R?raw=true")
```

## Housekeeping

-   **For our exam, should we know all the process of data analysis and the things we need to do during each of those steps?**

-   **I would like it if we could discuss our questions on the application assignments during lab**

-   **I would like the opportunity to ask questions about the application assignments during discussion**

-   **Will each assignment list all packages needed and allowed in the instruction?**

## Coding Questions

### Quarto

-   **what is with the use of `|>` in the example codes instead of `%>%`?? As far as I can tell, they are equivalent which is confusing**

example when `%>%` doesn't work but `|>` works
```{r}
data |> 
  select(where(is.numeric)) |> 
  names() |> 
  map(\(name) plot_hist(data, name)) |> 
  cowplot::plot_grid(plotlist = _, ncol = 2)

# The last line won't work if we use the "%>%" pipe operator
# data |> 
#   select(where(is.numeric)) |> 
#   names() |> 
#   map(\(name) plot_hist(data, name)) %>% 
#   cowplot::plot_grid(plotlist = _, ncol = 2)

data |> 
  select(where(is.numeric)) |> 
  names() |> 
  map(\(name) plot_hist(data, name)) %>%
  cowplot::plot_grid(plotlist = ., ncol = 2)
```

-   **what is the deal with these Quarto files? They seem just like R markdown, but slightly different, with buttons to "render" instead of "knit"**

> Both Quarto and R Markdown are markdown files that can be used for publishing. Quarto is the next generation of Rmd. It can be used to write a book, publish slides and so on. You can also use another coding langauge such as Python in quarto files.

-   **The other major difference that I have noticed is that Github Copilot in R does not work with Quarto files! I have messed around with it trying to fix it and it just does not make predictions when I am in a Quarto file. It works fine in a markdown file. Why do we use these Quarto things and do we have to use it? Can I do homework in R markdown with the same result? Is there a way to fix it so it will work with copilot?**

-   **Finally, and related to this Quarto stuff, I still do not really understand the whole "projects" framework. I have followed the instructions and set up a project as instructed, but I do not really understand why we do it.**

> Using R projects is good for path management so that when you are collaborating with people and would like to share your files, they can run the codes without specifying their own paths. 

> Another advantage of using R project is that you get clean workspace when switching between projects.


### Customized Functions

-   **The biggest one is how to write functions in R. If not that, can we go over how some of your custom functions work? Maybe we can look at regex?**

-   **Building functions and how to identify which pieces of code would be useful for a repeated function**

-   **I would like help or further discussion on making my own script with more helpful functions for future labs. I currently have an R script with some functions, but I want ones specific to this class.**

-   **Can we modify the functions John provided to create our own (e.g., different plotting aesthetics)?**

-   **What is the better way to build up my own function "database"? Using R script or GitHub repo?**

-   **I had a really hard time using the functions you recommended in lecture and ended up having to hard code and copy paste a lot of the functions. It also took me a long time to figure out how to install the functions you provided using devtools, but finally figured out that to install the packages for e1071 I had to set dependencies to true and I am not really sure why that is.**

#### Source functions

source functions from John's github repo
```{r}
# functions for EDA
devtools::source_url("https://github.com/jjcurtin/lab_support/blob/main/fun_eda.R?raw=true")
# functions for plotting
devtools::source_url("https://github.com/jjcurtin/lab_support/blob/main/fun_plots.R?raw=true")
```

modify an existing function
```{r}
plot_hist

function(df, x, bins = 100){
  df |>
    ggplot(aes(x = .data[[x]])) +
    geom_histogram(bins = bins) +
    theme(axis.text.x = element_text(size = 11),
          axis.text.y = element_text(size = 11))
}

new_plot_hist <- function(df, x, bins = 100){
  df |>
    ggplot(aes(x = .data[[x]])) +
    geom_histogram(bins = bins, fill = "#ADD8E6", color = "black") +
    theme(axis.text.x = element_text(size = 11),
          axis.text.y = element_text(size = 11))
}
```

source my own custimzed function from local files
```{r}
# source("functions_752.R")
```

### Data Wranggling

-   **How to use walk() and apply functions to all of a dataset instead of line by line**

-   **At least in the application assignment, I was having a difficult time using the map() function. The solution may have been simple as I can parse what its supposed to do but I don't think Ive seen an example of it being used in the slides? (unless I missed it)**

We typically don't use `map()` or `walk()` if we want to modify selected columns of the original dataframe. Instead, we use `mutate()` combined with `across()` to achieve it. Below is an example where we want all numeric columns to double.
```{r}
data |> 
  mutate(across(where(is.numeric), ~ .x * 2))
```

```{r}
# map() will return a list or vector
data |> 
  select(where(is.numeric)) |> 
  names() |> 
  map(\(name) plot_hist(data, name)) |>
  cowplot::plot_grid(plotlist = _, ncol = 2)

# walk() won't return anything
data |> 
  select(where(is.numeric)) |> 
  names() |> 
  walk(\(name) plot_hist(data, name)) |>
  cowplot::plot_grid(plotlist = _, ncol = 2)

# primarily used for printing, saving, modifying
data |> 
  select(where(is.numeric)) |> 
  names() |>
  walk(\(name) ggsave(paste0("plot_", name, ".png"), plot_hist(data, name)))
```

-   **If we could go over the set.seed() function a little more in detail? I googled it and just wanted to see if we could review it in layman's terms.**

```{r}
# randomly select a number from a list without setting a seed
runif(30)

set.seed(123)
runif(30)

set.seed(123)
runif(30)

set.seed(234)
runif(30)
```

### Missingness

-   **How to handle missing value. In your lecture, the missing value is actual no_garage. What about other methods like mean? How to choose among different handling method?**

-   **How can a specific missing value be assigned a particular value?**

> We can handle missingness by removing that specific observation in the *held-in data*. This method is usually not recommended as we will lose quality data if we have values in other columns. It'll also introduce bias to our analysis if missingness is associated with factors influencing our desired outcome. *YOU CANNOT DROP MISSING VALUES IN HELD OUT DATA.* There, you will have to impute (with imputation method and values determined from training data.)

> One other approach to handle missing values is to impute missing values with our best guess (e.g., mean). We can do this imputation when building our recipes. Importantly, our imputation value should be based on information in the training data only to avoid data leakage.

> NOTE: You can compare different methods to handle missingness by considering it as a model configuration.


```{r}
# imputation based on the variable
?step_impute_mean
?step_impute_median
?step_impute_mode

# imputation based on other variables
?step_impute_linear
?step_impute_knn
?step_impute_bag
```


### cleaning EDA

-   **Should discrete variables treated as continuous variables? I feel like this is up to the researcher, but I am curious how it should be treated in general.**

> Essentially, discrete variables need to be transformed into numeric values to be machine understandable. We have different ways to do this transformaton.

> If the variable is nominal (qualitative categories, no inherent order), we can do dummy coding, contrast coding, etc.

> If the variable is ordinal (inherent order but not equidistant spacing), we can either do dummy coding, contrast coding, etc, or treat them as ordered levels. You can choose between dummy versus step_ordinal (assigning ordered numbers) by treating these as different model configurations and comparing them using held-out (validation) data.

-   **Maybe fct_reorder? I used it in the application assignment but I low key don't really remember what it is.**

-   **Maybe going over fct_reorder and fct_relevel would be good. I feel like those could be a little confusing at times.**

Practical example: We have a factor with a likert scale of 1-5 (strongly disagree - strongly agree) and missing values. After reading the codebook, it appears that the missing value is due to a legitimate skip from an earlier question, which is actually meaningful. Therefore, we want to handle these missing values by transforming it into a different class called "legitimate skip" and reorder the levels so that they make sense.
```{r}
likert <- tibble(likert = factor(
  sample(
    c("strongly disagree", "disagree", "neutral", "agree", "strongly agree", NA),
    size = 20, replace = TRUE)
))

# check the existing levels
levels(likert$likert)

# create desired levels we want to encode our data
likert_levels <- c("strongly disagree", "disagree", "neutral", "agree",
                   "strongly agree", "legitimate skip")

likert <- likert |> 
  mutate(
    likert = fct_expand(likert, "legitimate skip"),
    likert = replace_na(likert, "legitimate skip"),
    likert = fct_relevel(likert, likert_levels)
  )

# Let's now see the numeric representations of our likert column!
likert$likert |> as.numeric()
```

-   **How to split the full data into training, validation and test data sets. I didn't understand completely from the slides the role of 'breaks' parameter while splitting the data. Also, function of recipes.**

-   **Train-test split. Also, I want to learn more on the Recipes package with samples.**

```{r}
splits <- data |> 
  initial_split(prop = 3/4, strata = "sale_price", breaks = 4)

splits |> analysis()
splits |> assessment()
```

With splits set up this way, you can extract train and test using `analysis()` and `assessment()`.

We will later use `initial_validation_split()` to create 3 resamples: training, validation, and test. We will extract those three resamples using `training()`, `validation()`, and `testing()`

```{r}
splits2 <- initial_validation_split(data) 

splits2 |> training()
splits2 |> validation()
splits2 |> testing()
```

### modeling EDA

-   **How to define which variable may have relationship with DV? Is there any requirements/techniques for that?**

-   **Also, I wonder if there is any tip for us to pick out the variables that might help for better understanding of another variable when analyzing the bivariate relationships during modeling EDA.**

-   **I feel a bit confused in question: Guided categorical exploration.**

### Plots

-   **How can we reorder the levels of a categorical variable in bar plots or other plots with the categorical variable on the x-axis?**

```{r}
# original plot
plot_bar(data, "utilities")

# change the order of categories
utility_levels <- c("NoSeWa", "NoSewr", "AllPub")
plot_bar(
  data |> mutate(utilities = fct_relevel(utilities, utility_levels)),
  "utilities"
)
```

-   **I would like to review interpretations of the many plots we learned in this unit (e.g., tile plot, stacked bar plot, etc.) and how to decide from certain plots if features are good predictors or if predictors need further editing (e.g., dealing with outliers, transformations).**

-   **When doing modeling EDA, I did the map and get all the bar plots I wanted for the ordinal categorical variables. However, the distribution of those data are not quite clear if it is normal or not as the order of the variables different. So the one with the most counts might be on the far left and the second most count might be on the far right. I do not know how to make the graph look more decent so I can tell the distribution.**

-   **One specific coding question would be how to use map() function to generate a number of plots after temporarily mutating the dataset.**

```{r}
data |> 
  select(where(is.numeric)) |> 
  names() |> 
  map(\(name) plot_hist(data, name)) |>
  cowplot::plot_grid(plotlist = _, ncol = 2)
```

### prep() and bake(), workflow, recipes

-   **Specific implementations and sequence of prep() and bake() when using recipes across training vs validation**

-   **I am a little bit confused about how to use recipes in tidymodels. I wish to have a demostration about how and when to use that.**

-   **Prepping and Baking a Recipe are little bit complicated. I think more hands-on practice with this function will be needed in the lab session.**

> We use `prep()` on the training/held-in data. We bake features for training using prepped recipe with `new_data = NULL`, and bake features for held-out (validation, test) by passing that dataset into `new_data`.

-   **I was a bit confused in terms of the assignment/work flow--were we supposed to do the transformations during modeling EDA or does that come at a later stage? (i think I got caught up on the word 'modeling' being in the title)**

> We do transformation when building recipes by using the step functions. 
