3 Mathematics


Scalars and vectors are probably your most common mathematical objects

3.1 Scalars

xs <- 2 # Your first scalar
xs  # Print the scalar
## [1] 2
(xs+1)^2 # Perform and print a simple calculation
## [1] 9
xs + NA # often used for missing values
## [1] NA
xs*2
## [1] 4

3.2 Vectors

x <- c(0,1,3,10,6) # Your First Vector
x # Print the vector
## [1]  0  1  3 10  6
x[2] # Print the 2nd Element; 1
## [1] 1
x+2 # Print simple calculation; 2,3,5,8,12
## [1]  2  3  5 12  8
x*2
## [1]  0  2  6 20 12
x^2
## [1]   0   1   9 100  36

Mathematical operations apply elementwise

x+x
## [1]  0  2  6 20 12
x*x
## [1]   0   1   9 100  36
x^x
## [1] 1.0000e+00 1.0000e+00 2.7000e+01 1.0000e+10 4.6656e+04
c(1) # scalars are vectors
## [1] 1
1:7
## [1] 1 2 3 4 5 6 7
seq(0,1,by=.1)
##  [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

3.3 Functions

Functions are applied to objects

# Define a function that adds two to any vector
add_2 <- function(input_vector) {
    output_vector <- input_vector + 2 # new object defined locally 
    return(output_vector) # return new object 
}
# Apply that function to a vector
x <- c(0,1,3,10,6)
add_2(x)
## [1]  2  3  5 12  8
# notice 'output_vector' is not available here

There are many many generalizations

add_vec <- function(input_vector1, input_vector2) {
    output_vector <- input_vector1 + input_vector2
    return(output_vector)
}
add_vec(x,3)
## [1]  3  4  6 13  9
add_vec(x,x)
## [1]  0  2  6 20 12
sum_squared <- function(x1, x2) {
    y <- (x1 + x2)^2
    return(y)
}

sum_squared(1, 3)
## [1] 16
sum_squared(x, 2)
## [1]   4   9  25 144  64
sum_squared(x, NA) 
## [1] NA NA NA NA NA
sum_squared(x, x)
## [1]   0   4  36 400 144
sum_squared(x, 2*x)
## [1]   0   9  81 900 324

Applying the same function over and over again

sapply(1:3, exp)
## [1]  2.718282  7.389056 20.085537
c( exp(1), exp(2), exp(3))
## [1]  2.718282  7.389056 20.085537
# More complex example
sapply(1:10, function(i){
    x <- i^(i-1)
    y <- x + mean( 0:i )
    z <- log(y)/i
    return(z)
})
##  [1] 0.4054651 0.5493061 0.7837918 1.0474137 1.2883487 1.4931972 1.6679272
##  [8] 1.8195116 1.9530885 2.0723266
# mapply takes multiple vectors
# mapply(sum, 1:3, exp(1:3) )

Functions can take functions as arguments

fun_of_seq <- function(f){
    x <- seq(1,3, length.out=12)
    y <- f(x)
    return(y)
}

fun_of_seq(mean)
## [1] 2
fun_of_seq(sd)
## [1] 0.6555548

3.4 Matrices

Matrices are objects

x1 <- c(1,4,9)
x2 <- c(3,0,2)
x_mat <- rbind(x1, x2)

x_mat       # Print full matrix
##    [,1] [,2] [,3]
## x1    1    4    9
## x2    3    0    2
x_mat[2,]   # Print Second Row
## [1] 3 0 2
x_mat[,2]   # Print Second Column
## x1 x2 
##  4  0
x_mat[2,2]  # Print Element in Second Column and Second Row
## x2 
##  0

There are elementwise operations

x_mat+2
x_mat*2
x_mat^2

x_mat + x_mat
x_mat*x_mat
x_mat^x_mat

There are some useful built in functions

m <- matrix(c(1:3,2*(1:3)),byrow=TRUE,ncol=3)
m
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    2    4    6
m/rowSums(m)
##           [,1]      [,2] [,3]
## [1,] 0.1666667 0.3333333  0.5
## [2,] 0.1666667 0.3333333  0.5
t(t(m)/colSums(m))
##           [,1]      [,2]      [,3]
## [1,] 0.3333333 0.3333333 0.3333333
## [2,] 0.6666667 0.6666667 0.6666667

You can apply functions to matrices

sum_squared(x_mat, x_mat)
##    [,1] [,2] [,3]
## x1    4   64  324
## x2   36    0   16
# Apply function to each matrix row
y <- apply(x_mat, 1, sum)^2 
# ?apply  #checks the function details
y - sum_squared(x, x) # tests if there are any differences
## [1]   192   -39 -2304

There are many possible functions to apply

# Return Y-value with minimum absolute difference from 3
abs_diff_y <- abs( y - 3 ) 
abs_diff_y # is this the luckiest number?
##  x1  x2 
## 193  22
min(abs_diff_y)
## [1] 22
which.min(abs_diff_y)
## x2 
##  2
y[ which.min(abs_diff_y) ]
## x2 
## 25

And you can also use matrix algebra

x_mat1 <- matrix(2:7,2,3)
x_mat1
##      [,1] [,2] [,3]
## [1,]    2    4    6
## [2,]    3    5    7
x_mat2 <- matrix(4:-1,2,3)
x_mat2
##      [,1] [,2] [,3]
## [1,]    4    2    0
## [2,]    3    1   -1
tcrossprod(x_mat1, x_mat2) #x_mat1 %*% t(x_mat2)
##      [,1] [,2]
## [1,]   16    4
## [2,]   22    7
crossprod(x_mat1, x_mat2)
##      [,1] [,2] [,3]
## [1,]   17    7   -3
## [2,]   31   13   -5
## [3,]   45   19   -7
# x_mat1 * x_mat2

3.5 Arrays

Generalization of matrices (often used in spatial econometrics)

a <- array(data = 1:24, dim = c(2, 3, 4))
a
## , , 1
## 
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
## 
## , , 2
## 
##      [,1] [,2] [,3]
## [1,]    7    9   11
## [2,]    8   10   12
## 
## , , 3
## 
##      [,1] [,2] [,3]
## [1,]   13   15   17
## [2,]   14   16   18
## 
## , , 4
## 
##      [,1] [,2] [,3]
## [1,]   19   21   23
## [2,]   20   22   24
a[1, , , drop = FALSE]  # Row 1
## , , 1
## 
##      [,1] [,2] [,3]
## [1,]    1    3    5
## 
## , , 2
## 
##      [,1] [,2] [,3]
## [1,]    7    9   11
## 
## , , 3
## 
##      [,1] [,2] [,3]
## [1,]   13   15   17
## 
## , , 4
## 
##      [,1] [,2] [,3]
## [1,]   19   21   23
#a[, 1, , drop = FALSE]  # Column 1
#a[, , 1, drop = FALSE]  # Layer 1

a[ 1, 1,  ]  # Row 1, column 1
## [1]  1  7 13 19
#a[ 1,  , 1]  # Row 1, "layer" 1
#a[  , 1, 1]  # Column 1, "layer" 1
a[1 , 1, 1]  # Row 1, column 1, "layer" 1
## [1] 1

Apply extends to arrays

apply(a, 1, mean)    # Row means
## [1] 12 13
apply(a, 2, mean)    # Column means
## [1] 10.5 12.5 14.5
apply(a, 3, mean)    # "Layer" means
## [1]  3.5  9.5 15.5 21.5
apply(a, 1:2, mean)  # Row/Column combination 
##      [,1] [,2] [,3]
## [1,]   10   12   14
## [2,]   11   13   15

Outer products yield arrays

x <- c(1,2,3)
x_mat1 <- outer(x, x) # x %o% x
x_mat1
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    2    4    6
## [3,]    3    6    9
is.array(x_mat) # Matrices are arrays
## [1] TRUE
x_mat2 <- matrix(6:1,2,3)
outer(x_mat2, x)
## , , 1
## 
##      [,1] [,2] [,3]
## [1,]    6    4    2
## [2,]    5    3    1
## 
## , , 2
## 
##      [,1] [,2] [,3]
## [1,]   12    8    4
## [2,]   10    6    2
## 
## , , 3
## 
##      [,1] [,2] [,3]
## [1,]   18   12    6
## [2,]   15    9    3
# outer(x_mat2, matrix(x))
# outer(x_mat2, t(x))
# outer(x_mat1, x_mat2)