Problem 1

  1. Write an R function that accepts an n × n matrix A = (aij ) as an argument and returns the trace of A, trace(A) = Pni=1 aii. Include code that verifies that the function’s argument is indeed a square matrix. Also include comments that describe the function’s purpose, argument and output. The following code generates a list of 25 matrices of different dimensions.

matrix.list <- lapply(1:25, FUN=function(x) {matrix(1:x^2, nrow=x, ncol=x)})

matrix.list <- lapply(1:25, FUN=function(x) {matrix(1:x^2, nrow=x, ncol=x)})

A <- as.matrix(data.frame(c(4,8,1),c(3,-2,1),c(-4,2,3)))
A
##      c.4..8..1. c.3...2..1. c..4..2..3.
## [1,]          4           3          -4
## [2,]          8          -2           2
## [3,]          1           1           3
trace <- function(A) {
  n <- dim(A)[1]
  tr <- 0
  
  for (k in 1:n) {
    l <- A[k,k]
    tr <- tr + l
  }
  return(tr[[1]])
}
trace(A)
## [1] 5

Apply your trace function to each matrix in this list.

lapply(matrix.list,trace)
## [[1]]
## [1] 1
## 
## [[2]]
## [1] 5
## 
## [[3]]
## [1] 15
## 
## [[4]]
## [1] 34
## 
## [[5]]
## [1] 65
## 
## [[6]]
## [1] 111
## 
## [[7]]
## [1] 175
## 
## [[8]]
## [1] 260
## 
## [[9]]
## [1] 369
## 
## [[10]]
## [1] 505
## 
## [[11]]
## [1] 671
## 
## [[12]]
## [1] 870
## 
## [[13]]
## [1] 1105
## 
## [[14]]
## [1] 1379
## 
## [[15]]
## [1] 1695
## 
## [[16]]
## [1] 2056
## 
## [[17]]
## [1] 2465
## 
## [[18]]
## [1] 2925
## 
## [[19]]
## [1] 3439
## 
## [[20]]
## [1] 4010
## 
## [[21]]
## [1] 4641
## 
## [[22]]
## [1] 5335
## 
## [[23]]
## [1] 6095
## 
## [[24]]
## [1] 6924
## 
## [[25]]
## [1] 7825

Problem 2

Creating test vectors

x <- c(1,-2,3,4,5)
y <- c(1,2,3,4,5)

Creating a fuction for Geometric Mean

gm <- function(x){
  exp(mean(log(x)))
}
gm(x)
## Warning in log(x): NaNs produced
## [1] NaN
gm(y)
## [1] 2.605171

Create a data set to test function

set.seed(123)
data <- matrix(rnorm(10000, mean=3), ncol=25,
dimnames=list(NULL, paste("X", 1:25, sep=".")))

Apply Function to each column of data and create an output vector

gm.col <- apply(data,MARGIN = 2, FUN = gm)
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced
## Warning in log(x): NaNs produced

View the output vector gm.col to see valid columns and invalid columns

gm.col
##      X.1      X.2      X.3      X.4      X.5      X.6      X.7      X.8 
## 2.845667 2.790897 2.851296 2.832801      NaN 2.746103 2.784419 2.778567 
##      X.9     X.10     X.11     X.12     X.13     X.14     X.15     X.16 
##      NaN 2.792840 2.745977      NaN      NaN      NaN      NaN      NaN 
##     X.17     X.18     X.19     X.20     X.21     X.22     X.23     X.24 
## 2.809164      NaN      NaN      NaN 2.861628      NaN 2.741230 2.769901 
##     X.25 
##      NaN

Problem 3

Create a function called middle to read the middle 6 rows of data in a data frame

middle <- function(df){
  n <- nrow(df)
  df[(floor(n/2) - 2):(floor(n/2) + 3),]
}

Testing the middle function on iris data. Note : the iris data is 150 rows long so we want rows 73-78

middle(iris)
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 73          6.3         2.5          4.9         1.5 versicolor
## 74          6.1         2.8          4.7         1.2 versicolor
## 75          6.4         2.9          4.3         1.3 versicolor
## 76          6.6         3.0          4.4         1.4 versicolor
## 77          6.8         2.8          4.8         1.4 versicolor
## 78          6.7         3.0          5.0         1.7 versicolor

Create a pick function that does the same as middle.

pick <- function(df,p,k){
  p = p
  k = k
  n = nrow(df)
  
  if (k%%2 == 0){
    return(df[(n*p - ceiling(k/2) + 1):(n*p + ceiling(k/2)),])
  }
  else if (k%%2 != 0){
    return(df[(n*p - ceiling(k/2) + 1):(n*p + floor(k/2)),])
  }
  
  
}

pick(iris,p = .5, k = 6)
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 73          6.3         2.5          4.9         1.5 versicolor
## 74          6.1         2.8          4.7         1.2 versicolor
## 75          6.4         2.9          4.3         1.3 versicolor
## 76          6.6         3.0          4.4         1.4 versicolor
## 77          6.8         2.8          4.8         1.4 versicolor
## 78          6.7         3.0          5.0         1.7 versicolor

Problem 4

Create a matrix 100x100 filled with random numbers that follow a uniform distribution U[0,1]. Call the matrix M

M <- matrix(runif(1000,0,1),nrow = 100, ncol = 100)

Create a vector of the means of the columns

means <- colMeans(M,na.rm = FALSE)

Plot a histogram of vector “means”

hist(means, breaks = 20)
print(hist(means, breaks = 20))

## $breaks
##  [1] 0.455 0.460 0.465 0.470 0.475 0.480 0.485 0.490 0.495 0.500 0.505 0.510
## [13] 0.515 0.520 0.525 0.530 0.535 0.540 0.545 0.550
## 
## $counts
##  [1] 20  0  0 10  0  0 20  0 10 10 10  0  0  0  0 10  0  0 10
## 
## $density
##  [1] 40  0  0 20  0  0 40  0 20 20 20  0  0  0  0 20  0  0 20
## 
## $mids
##  [1] 0.4575 0.4625 0.4675 0.4725 0.4775 0.4825 0.4875 0.4925 0.4975 0.5025
## [11] 0.5075 0.5125 0.5175 0.5225 0.5275 0.5325 0.5375 0.5425 0.5475
## 
## $xname
## [1] "means"
## 
## $equidist
## [1] TRUE
## 
## attr(,"class")
## [1] "histogram"

Does this look like a normal distribution?

At first glance this does not look like it follows a normal distribution. However, it does appear that almost all the values are in a tight range considering the underlying range of the uniform this came from is [0,1]

Repeat this process for (b) U[0,100], (c) U[10,2000], (d) U[-500,0]

  1. U[0,100]
M.b <- matrix(runif(1000,0,100),nrow = 100, ncol = 100)
means.b <- colMeans(M.b,na.rm = FALSE)
hist(means.b)

  1. U[10,2000]
M.c <- matrix(runif(1000,10,2000),nrow = 100, ncol = 100)
means.c <- colMeans(M.c,na.rm = FALSE)
hist(means.c)

  1. U[-500,0]
M.d <- matrix(runif(1000,-500,0),nrow = 100, ncol = 100)
means.d <- colMeans(M.d,na.rm = FALSE)
hist(means.d)

Verify if the Central Limit Theorem still holds, and write a short note on your findings.

This is tough for me to say anything for certain. The ranges on the histograms all hover around the true mean of the underlying distributions, but the histograms themselves don’t look like normal curves. I can not explain why this is. I even changed the number of breaks in M to 20 and it doesn’t appear to change anything.