#### First steps in R ####

# Everything that follows is extremely inaccurate!
# https://smikula.shinyapps.io/trafficacc/

#### Variables ####

# What can I do in R?

1+1 

# Result is printed on the screen and then eaten by the garbage collector
# If we want to keep it we need to learn about objects/variables


# User can create objects ("varibles") that are stored in # global environment 
# (workspace). If we want to create an object in the global environment we need 
# to use assignment function '<-' ('->' works too, but it is not wise to use it)

x <- 1 + 1

# And we have a variable 'x' we can print or use later.

x # or print(x)

# There is a lot of types and classes of variables:

class(1.5)    # double & numeric
class(1L)     # integer & numeric
class("a")    # character
class(TRUE)   # logical

# We usually do not work with one number (scalar) but with vectors.
# We create vectors using function c():

v <- c("a","b","c","d","e")
v <- c(1,2,3,4,5)

is.vector(v)

# More complicated object is list, created by calling function list(). List can
# contain an unlimited number number of items. Items do not need to share attributes
# or other properties.

l <- list(
  c("a","b","c"),
  c(1,2,3,4,5)
)

# List l contains two items of different length and type.

class(l)
str(l)

# Imagine we could have list with n items: atomic vectors of length m. We can 
# also name items of the list:

l <- list(
  col1 = c("a","b","c"),
  col2 = c(1,2,3)
)

str(l)

# In essence such a data structure corresponds to an "Excel sheet". R has a data 
# type that corresponds to Excel sheet: data frame

df <- data.frame(l)
class(df)

# Data frame is indeed just a special case of a list:
str(df)

l <- list(
  col1 = c("a","b"),
  col2 = c(1,2,3)
)

data.frame(l) # data.frame must be rectangular

# Note: R can also handle matrices, but these are rarely used. You definitely do
# not need matrices for introductory econometrics.

# Basic econometrics rests on data frames!

#### Programming in R: 1 ####

# You can do everything in code in R. This is a great thing but it requires some
# rather heavy initial investments.

# Tasks:
# Step 1: Create script: a text file (*.R) that is processed by R row by row
# Step 2: Set working directory (Where should be R looking for your scripts?)
# Step 3: Create a numeric vector X
# Step 4: calculate mean of X (Here you need to use a function. Which one?)
# Step 5: Try to repeat step 4 with a pipe (|>)


#### Sub-setting ####

v <- c("a","b","c","d","e")

# Get third element of vector v:
v[3]

# Get first and third element of vector v:
v[c(1,3)]

# Similarly to lists the elements could also have names:
v <- c(a = 1, b = 2, c = 3, d = 4, e = 5)

# ...if so one can also use names for sub-setting:
v["a"]
v[c("a","c")]

#### Libraries ####

# 'Base R' is just a core with basic functions. All good things are coming in packages/libraries.
# There is a huge amount of packages published at CRAN. For instance:

# ggplot2...create world-class figures
# sf...if you want to work with maps
# fixest...for standard econometrics

# There is a highly popular collection of packages called 'tidyverse' (dplyr,
# purrr, ggplot2, tidyr, stringr, tibble, readr,...)

# You need to install packages first. But you need to load them every time:

library(tidyverse)

#### Read data ####

# You can get data for your analysis from various sources. Most of them can be 
# loaded in R. The most common scenario is reading rectangular text data (~CSV)
# or loading data from R binary format.

# Read CSV/TSV/... with readr::read_csv()

# read_csv(
#   file,
#   col_names = TRUE,
#   col_types = NULL,
#   col_select = NULL,
#   id = NULL,
#   locale = default_locale(),
#   na = c("", "NA"),
#   quoted_na = TRUE,
#   quote = "\"",
#   comment = "",
#   trim_ws = TRUE,
#   skip = 0,
#   n_max = Inf,
#   guess_max = min(1000, n_max),
#   name_repair = "unique",
#   num_threads = readr_threads(),
#   progress = show_progress(),
#   show_col_types = should_show_types(),
#   skip_empty_rows = TRUE,
#   lazy = should_read_lazy()
# )

# Task:
# Read data from "IRIS.CSV"
read_csv("IRIS.CSV") 
# Where is the problem?
# (a) Do you have the file in your working directory? Is your path correct?
# (b) R is case sensitive: iris.csv is NOT the same as IRIS.CSV:
"iris.csv" == "IRIS.CSV"

iris <- read_csv("iris.csv") 
class(iris) 
# readr creates special data frames (tibbles: tbl_df). 
# Advice: use tibble whenever possible

iris

# Function load() loads data from binary files:
load("iris.RData")


#### Econometrics in R ####

# Most of the econometrics functions in R share interface built on Three Elements:
# 1) Formula
# 2) Data
# 3) Estimator (estimation function)

#...which follows the logic of econometric analysis.

# There is a simple first-to-learn function in R called lm() (OLS estimator):

# lm(formula, data, subset, weights, na.action,
#    method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE,
#    singular.ok = TRUE, contrasts = NULL, offset, ...)

# Formula --- "formula" parameter
# Data --- "data" parameter
# Estimator --- lm() function

library(Formula) # Adds some advanced functions for creating/modifying formulas

names(iris)

# Sepal.Length = a + b*Sepal.Width + c*Petal.Length + d*Petal.Width + Species
Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width + Species
# Note that constant (a) is included by default! You can removing by adding '-1':
Sepal.Length ~ -1 + Sepal.Width + Petal.Length + Petal.Width + Species
# Formula can by assigned to a variable (it is just another object):
f <- Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width + Species

# Estimate it!
lm(
  f,
  iris
)

# Get summary:
lm(
  f,
  iris
) |>
  summary()
# Outcome of the lm() is an object that can be further processed by a number of 
# functions.

# Formulas allows you conduct data transformations:
f <- Sepal.Length ~ log(Sepal.Width) + I(Petal.Length^2) + Petal.Width + Species
# ...or create interactions:
f <- Sepal.Length ~ Sepal.Width:Petal.Length + Petal.Width + Species
f <- Sepal.Length ~ Sepal.Width*Petal.Length + Petal.Width + Species

# The same with fixest::feols():

# feols(
#   fml,
#   data,
#   vcov,
#   weights,
#   offset,
#   subset,
#   split,
#   fsplit,
#   cluster,
#   se,
#   ssc,
#   panel.id,
#   fixef,
#   fixef.rm = "none",
#   fixef.tol = 1e-06,
#   fixef.iter = 10000,
#   collin.tol = 1e-10,
#   nthreads = getFixest_nthreads(),
#   lean = FALSE,
#   verbose = 0,
#   warn = TRUE,
#   notes = getFixest_notes(),
#   only.coef = FALSE,
#   combine.quick,
#   demeaned = FALSE,
#   mem.clean = FALSE,
#   only.env = FALSE,
#   env,
#   ...
# )

feols(
  # A multipart formula:
  Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width | Species,
  # Data
  iris,
  # vcov:
  vcov = "HC1",
  # cluster = ~ Species,
) |>
  etable()


# Special cases:

# Estimate the same specification using different samples
feols(
  Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width,
  iris,
  split = ~Species
) |>
  etable()

# Estimate different specifications on the same sample
feols(
  Sepal.Length ~ csw0(Sepal.Width,Petal.Length) + Petal.Width,
  iris
) |>
  etable()

# Combine both:
feols(
  Sepal.Length ~ csw0(Sepal.Width,Petal.Length) + Petal.Width,
  iris,
  split = ~Species
) |>
  etable()


#### Iterators ####

# Loops

for(p in 1:10){
  mean(1:p) |> print()
}

# Loops are helpful but are considered inferior in R (poor memory allocation, 
# performance,...). In R we use iterators:

i <- 1:10 |>
  # There is a whole family of map*() in purrr
  map_dbl(
    function(x){
      mean(1:x)
    }
  )
i

# ...with iterators you need to know something about functions.

# Function with one input:
my_function <- function(x){
  mean(1:x)
}

my_function(10)

# Function with multiple inputs:
my_function <- function(x,y){
  mean(x:y)
}

my_function(1,10)

# Example with map() iterator uses a lambda (anonymous) function that is created
# in each iteration (and eaten by garbage collector each time)

# ONE NEEDS TO BE VERY CAREFUL WHEN USING FUNCTIONS. OUR EXAMPLES ARE VERY SIMPLE
# BUT TO USE FUNCTION PROPERLY ONE SHOULD KNOW A LOT ABOUT INNER PARTS OF R!