Task 1: Matrix Operations

a. Generate matrix dimensions
n_dims <- sample(3:10, size=1)
n_dims
## [1] 4
b. Create randomized square matrix
vector <- sample(seq(1, n_dims^2))
matrix1 <- matrix(vector, nrow = n_dims)
print(matrix1)
##      [,1] [,2] [,3] [,4]
## [1,]   16    6   11    5
## [2,]   12   14    9    1
## [3,]    7    3    2   10
## [4,]    8   13   15    4
c. Transpose matrix
transposed_matrix <- t(matrix1)
print(transposed_matrix)
##      [,1] [,2] [,3] [,4]
## [1,]   16   12    7    8
## [2,]    6   14    3   13
## [3,]   11    9    2   15
## [4,]    5    1   10    4
d. Compute Basic Statistics on Specific Rows
first_row_mean <- mean(matrix1[1, ])
first_row_sum <- sum(matrix1[1, ])
last_row_mean <- mean(matrix1[n_dims, ])
last_row_sum <- sum(matrix1[n_dims, ])
list(first_row_mean, first_row_sum, last_row_mean, last_row_sum)
## [[1]]
## [1] 9.5
## 
## [[2]]
## [1] 38
## 
## [[3]]
## [1] 10
## 
## [[4]]
## [1] 40
e. Perform Eigenvalue Analysis
matrix_eigen <- eigen(matrix1)
print(matrix_eigen)
## eigen() decomposition
## $values
## [1] 33.642719+0.000000i -8.390689+0.000000i  5.373985+3.872704i
## [4]  5.373985-3.872704i
## 
## $vectors
##               [,1]          [,2]                  [,3]                  [,4]
## [1,] -0.5498159+0i  0.1694461+0i  0.2326025-0.4434339i  0.2326025+0.4434339i
## [2,] -0.5224357+0i  0.1846883+0i -0.5910992+0.0000000i -0.5910992+0.0000000i
## [3,] -0.3457559+0i -0.7530067+0i  0.2572282+0.2808099i  0.2572282-0.2808099i
## [4,] -0.5524638+0i  0.6084070+0i -0.0074529+0.5047654i -0.0074529-0.5047654i
f. Check Types of Eigenvalues and Eigenvectors
typeof(matrix_eigen$values)
## [1] "complex"
typeof(matrix_eigen$vectors)
## [1] "complex"

Task 2: Creating and Manipulating Lists

a. Build a List Containing Different Data Types
# Create a 4x4 matrix with random uniform values
my_matrix <- matrix(runif(16), nrow=4)

# Generate a logical vector of TRUE/FALSE values
my_logical <- (runif(100) > 0.8)

# Generate a randomized sequence of lowercase letters
my_letters <- sample(letters)
b. Extract and Store Specific Elements into a New List
# Combine the objects into one list
list1 <- list(my_matrix, my_logical, my_letters)

# Extract the second element from each and store in a new list
new_list <- list(my_matrix[2, 2], my_logical[2], my_letters[2])
c. Check Data Types of Extracted Elements
# Inspect the type of each item in new_list
typeof(new_list[[1]])  # numeric
## [1] "double"
typeof(new_list[[2]])  # logical
## [1] "logical"
typeof(new_list[[3]])  # character
## [1] "character"
d. Merge Elements into a Single Vector
# Combine all extracted values into one atomic vector
combined_elements_vector <- c(new_list[[1]], new_list[[2]], new_list[[3]])

# View the merged vector and its type
print(combined_elements_vector)
## [1] "0.239589131204411" "FALSE"             "c"
typeof(combined_elements_vector)
## [1] "character"

Task 3: Data Frames and Handling Missing Data

a. Construct Data Frame
# Create a data frame with two columns:
# - Random uniform values between 0 and 10
# - Randomly ordered capital letters
dataframe <- data.frame(
  my_unis = runif(26, min = 0, max = 10),
  my_letters = sample(LETTERS)
)

print(dataframe)
##      my_unis my_letters
## 1  7.6179680          G
## 2  7.4529740          B
## 3  7.0782726          Q
## 4  9.8680824          X
## 5  4.5163091          L
## 6  1.1821741          Z
## 7  2.3863532          H
## 8  4.7052276          N
## 9  3.5232307          F
## 10 3.3857524          C
## 11 1.2730127          K
## 12 4.2407386          V
## 13 4.7331084          S
## 14 5.2772201          O
## 15 6.2695361          J
## 16 8.7602609          P
## 17 6.7915704          M
## 18 7.2406401          T
## 19 1.8184772          R
## 20 0.7785552          E
## 21 0.7219740          A
## 22 0.5406259          Y
## 23 5.1727341          W
## 24 8.1405157          I
## 25 4.4904840          D
## 26 5.5889489          U
b. Introduce Missing Values
# Replace four values in the numeric column with NA
dataframe[sample(1:26, size = 4), 1] <- NA
b. Identify Positions of Missing Data
# Locate the rows where NA values appear
which(is.na(dataframe$my_unis))
## [1]  5  6 13 21

Reorder Data by Alphabetical Order

# Sort the data frame alphabetically by the letter column
dataframe <- dataframe[order(dataframe$my_letters), ]
print(dataframe)
##      my_unis my_letters
## 21        NA          A
## 2  7.4529740          B
## 10 3.3857524          C
## 25 4.4904840          D
## 20 0.7785552          E
## 9  3.5232307          F
## 1  7.6179680          G
## 7  2.3863532          H
## 24 8.1405157          I
## 15 6.2695361          J
## 11 1.2730127          K
## 5         NA          L
## 17 6.7915704          M
## 8  4.7052276          N
## 14 5.2772201          O
## 16 8.7602609          P
## 3  7.0782726          Q
## 19 1.8184772          R
## 13        NA          S
## 18 7.2406401          T
## 26 5.5889489          U
## 12 4.2407386          V
## 23 5.1727341          W
## 4  9.8680824          X
## 22 0.5406259          Y
## 6         NA          Z

Compute the Mean of the Numeric Column

# Calculate the mean of the numeric column, excluding NAs
mean(dataframe$my_unis, na.rm = TRUE)
## [1] 5.109145