---
title: "Code for Session 1 Sup"
author: "Dr. Richard M. Crowley"
format:
  html:
    code-tools: true
    code-link: true
    embed-resources: true
---

Note that the directories used to store data are likely different on your computer, and such references will need to be changed before using any such code.

```{r helpers, warning=FALSE, message=F}
library(knitr)
library(kableExtra)

#' Pretty formatted HTML tables
#' 
#' @param df The dataframe to format as a table
#' @param names Names to use for columns if not using the df column names. Vector
#' @param highlight_cols Columns to highlight. Default is c(1) for highlighting the first row. Use c() to remove.
#' @param highlight_rows Rows to highlight. Default is c() to not highlight any rows.
#' @param color_rows Rows to highlight in color. Default is c() to not highlight any rows.
#' @param highlight_end_rows Rows to highlight. Uses a reverse indexing where 1 is the last row, 2 is second to last, etc.
#' @param full Use to span the full width of a slide. FALSE by default.
#' @param fixed_header Whether the first row should be treated as a header row. TRUE by default.
html_df <- function(df, names=NULL, highlight_cols=c(1), highlight_rows=c(), color_rows=c(), highlight_end_rows=c(), full=F, fixed_header=T) {
  if(!length(names)) {
    names=colnames(df)
  }
  kbl(df,"html", col.names = names, align = c("l",rep('c',length(cols)-1))) %>%
    kable_paper(c("striped","hover"), full_width=full, fixed_thead=F, html_font = "\"Source Sans Pro\", Helvetica, sans-serif") %>%
    {if(length(highlight_cols)) column_spec(., highlight_cols,bold=T, background = "#ffffff99") else .} %>%
    {if(length(highlight_rows)) row_spec(., highlight_rows,bold=T, background = "#ffffff99") else .} %>%
    {if(length(color_rows)) row_spec(., color_rows,bold=T, background = "#aaaaff99") else .} %>%
    {if(length(highlight_end_rows)) row_spec(., nrow(df) + 1 - highlight_end_rows,bold=T, background = "#ffffff99") else .}
}

library(tidyverse)
```

```{r}
#| include: false
options(downlit.attached = c("knitr", "kableExtra", "tidyverse"))
```

```{r, eval=TRUE}
company <- c("Google", "Microsoft", "Goldman")
company

tech_firm <- c(TRUE, TRUE, FALSE)
tech_firm

earnings <- c(12662, 21204, 4286)
earnings
```

```{r}
1:5
seq(from=0, to=100, by=5)
```

```{r}
rep(1,times=10)
rep("hi",times=5)
```

```{r, eval=TRUE}
earnings  # previously defined
earnings + earnings  # Add element-wise
earnings * earnings  # multiply element-wise
```

```{r, eval=TRUE}
earnings + 10000  # Adding a scalar to a vector
10000 + earnings  # Order doesn't matter
earnings / 1000  # Dividing a vector by a scalar
```

```{r}
# Dot product: sum of product of elements
earnings %*% earnings  # returns a matrix though...
drop(earnings %*% earnings)  # Drop drops excess dimensions
```

```{r}
length(earnings)  # returns the number of elements
sum(earnings)  # returns the sum of all elements
```

```{r, eval=TRUE}
earnings
```

```{r, eval=TRUE}
names(earnings) <- c("Google",
                     "Microsoft",
                     "Goldman")
earnings
```

```{r, eval=TRUE}
# Equivalently:
names(earnings) <- company
earnings
```

```{r}
earnings[1]
earnings["Google"]
```

```{r}
# Each of the above 3 is equivalent
earnings[1:2]
```

```{r}
c1 <- c(1,2,3)
c2 <- c(4,5,6)
c3 <- c(c1,c2)
c3
```

```{r}
library(tidyverse)
df <- read.csv("../../Data/Session_1-2.csv")
# Filter to firms with at least $1M USD revenue, known net income, and fiscal year of 2017
clean_df <- df %>% filter(fyear==2017, !is.na(revt), !is.na(ni), revt > 1)
tech_df <- clean_df %>%
  filter(gsector==45) %>%
  mutate(revenue = revt,
         earnings = ni,
         margin = ni/revt)
earnings_2017 <- tech_df$ni
revenue_2017 <- tech_df$revt
names_2017 <- tech_df$conm
names(earnings_2017) <- names_2017
names(revenue_2017) <- names_2017
```

```{r, eval=TRUE}
# Calculating proit margin for all public US tech firms
# 715 tech firms with >1M sales in 2017
summary(earnings_2017)  # Cleaned data from Compustat, in $M USD
```

```{r, eval=TRUE}
summary(revenue_2017)  # Cleaned data from Compustat, in $M USD
```

```{r, eval=TRUE}
profit_margin <- earnings_2017 / revenue_2017
summary(profit_margin)
```

```{r, eval=TRUE}
# These are the worst, midpoint, and best profit margin firms in 2017. Our names carried over :)
profit_margin[order(profit_margin)][c(1,length(profit_margin)/2,length(profit_margin))]
```

```{r, eval=TRUE}
columns <- c("Google", "Microsoft", "Goldman")
rows <- c("Earnings","Revenue")

# equivalent: matrix(data=c(12662, 21204, 4286, 110855, 89950, 42254),ncol=3)
firm_data <- matrix(data=c(12662, 21204, 4286, 110855, 89950, 42254),nrow=2)
firm_data

```

```{r}
firm_data + firm_data
firm_data / 1000
```

```{r}
firm_data_T <- t(firm_data)
firm_data_T
```

```{r}
firm_data %*% firm_data_T
```

```{r}
rownames(firm_data) <- rows
colnames(firm_data) <- columns
firm_data
```

```{r}
firm_data[2,3]
firm_data[,c("Google","Microsoft")]
firm_data[1,]
```

```{r}
indcode <- c(45,45,40)
jpdata <- c(17370, 115475)
# Preloaded: industry codes as indcode (vector)
```

```{r}
# Preloaded: industry codes as indcode (vector)
#     - GICS codes: 40=Financials, 45=Information Technology
#     - See: https://en.wikipedia.org/wiki/Global_Industry_Classification_Standard
# Preloaded: JPMorgan data as jpdata (vector)

mat <- rbind(firm_data,indcode)  # Add a row
rownames(mat)[3] <- "Industry"  # Name the new row
mat
mat <- cbind(firm_data,jpdata)  # Add a column
colnames(mat)[4] <- "JPMorgan"  # Name the new column
mat
```

```{r}
# Ignore this code for now...
model <- summary(lm(earnings ~ revenue, data=tech_df))
#Note that this function is hiding something...
model
```

```{r}
model["r.squared"]
model[["r.squared"]]
model$r.squared
```

```{r}
earnings["Google"]
earnings[["Google"]]
#Can't use $ with vectors
```

```{r}
str(model)
```

```{r}
library(DT) # This library is great for including larger collections of data in output
options(DT.options = list(scrollY="450px"))
```

```{r, warning=FALSE}
# The DT library is great for including larger collections of data in output
DT::datatable(tech_df[1:20,c("conm","tic","margin")], rownames=FALSE)
```

```{r}
df <- data.frame(companyName=company,
                 earnings=earnings,
                 tech_firm=tech_firm)
df
```

```{r}
df[,1]
```

```{r}
df$companyName
df[[1]]
```

```{r}
df$all_zero <- 0
df$revenue <- c(110855, 89950, 42254)
df$margin <- df$earnings / df$revenue
# Custom function for small tables -- see last slide for code
html_df(df)
```

```{r}
sort(df$earnings)
```

```{r}
ordering <- order(df$earnings)
ordering
df <- df[ordering,]
df
```

```{r}
# Example of multicolumn sorting:
example <- data.frame(firm=c("Google","Microsoft","Google","Microsoft"),
                      year=c(2017,2017,2016,2016))
example

# with() allows us to avoiding prepending each column with "example$"
ordering <- order(example$firm, example$year)
example <- example[ordering,]
example
```

```{r}
df[df$tech_firm,]  # Remember the comma!
```

```{r}
subset(df,earnings < 20000)
```

```{r}
df$earnings
df$earnings < 20000
```

```{r}
sum(tech_df$revenue > 10000)
```

```{r}
sum(tech_df$revenue > 10000 & tech_df$earnings < 0)
```

```{r}
columns <- c("conm","tic","earnings","revenue")
tech_df[tech_df$revenue > 10000 & tech_df$earnings < 0, columns]
```

```{r}
# Outputs odd for odd numbers and even for even numbers
even <- rep("even",5)
odd <- rep("odd",5)
numbers <- 1:5
ifelse(numbers %% 2, odd, even)
```

```{r}
i = 0
while(i < 5) {
  print(i)
  i = i + 2
}
```

```{r}
for(i in c(0,2,4)) {
  print(i)
}
```

```{r}
# Profit margin, all US tech firms
start <- Sys.time()
margin_1 <- rep(0,length(tech_df$ni))
for(i in seq_along(tech_df$ni)) {
  margin_1[i] <- tech_df$earnings[i] /
                 tech_df$revenue[i]
}
end <- Sys.time()
time_1 <- end - start
time_1
```

```{r}
# Profit margin, all US tech firms
start <- Sys.time()
margin_2 <- tech_df$earnings /
            tech_df$revenue
end <- Sys.time()
time_2 <- end - start
time_2
```

```{r}
identical(margin_1, margin_2)  # Are these calculations identical?  Yes they are.
paste(as.numeric(time_1) / as.numeric(time_2), "times") # How much slower is the loop?
```

```{r}
args(data.frame)
```

```{r}
args(data.frame)
```

```{r}
#| eval: true
#| echo: true
#| fig-width: 6
#| fig-height: 3.5
#| fig-align: center

library(tidyverse)
library(plotly)

plot <- tech_df %>%
  subset(revenue > 10000) %>%
  ggplot(aes(x=revenue,y=earnings)) + # ggplot comes from ggplot2, part of tidyverse
  geom_point(shape=1, aes(text=sprintf("Ticker: %s", tic)))  # Adds point, and ticker
ggplotly(plot)  # Makes the plot interactive
```

```{r}
#| eval: true
#| echo: true
#| fig-width: 6
#| fig-height: 3.5
#| fig-align: center

library(tidyverse)
library(plotly)

plot <- ggplot(subset(tech_df, revenue > 10000), aes(x=revenue,y=earnings)) +
  geom_point(shape=1, aes(text=sprintf("Ticker: %s", tic)))
ggplotly(plot)  # Makes the plot interactive
```

```{r}
vector = c(-2,-1,0,1,2)
sum(vector)
abs(vector)
sign(vector)
```

```{r}
quantile(tech_df$earnings)
range(tech_df$earnings)
```

```{r}
add_two <- function(n) {
  n + 2
}

add_two(500)
```

```{r}
mult_together <- function(n1, n2=0, square=FALSE) {
  if (!square) {
    n1 * n2
  } else {
    n1 * n1
  }
}

mult_together(5,6)
mult_together(5,6,square=TRUE)
mult_together(5,square=TRUE)
```

