I am trying to work out an issue regarding the order of eigenvectors returned by eigen in r. Consider the following:
covmatrix <- matrix(data = c(13, 5, 2, 4), nrow = 2, ncol = 2)
covmatrix
eigen <- eigen(covmatrix)
eigen
The output returns:
values
[1] 14 3
vectors
[,1] [,2]
[1,] 0.8944272 -0.1961161
[2,] 0.4472136 0.9805807
Per the documentation, the first column should represent the eigenvector associated with the largest eigenvalue. However, mathematically, when I calculate the eigenvectors I end up with column 2 associated with the eigenvalue 14 as 0.9805807 is 5 times 0.1961161. The math is detailed here. I'm sure I am missing something simple but can't quite work it out.
You are not working with the same matrix. To get consistent result with what you derive analytically, you need
covmatrix <- matrix(data = c(13, 5, 2, 4), nrow = 2, ncol = 2, byrow = TRUE)
eigen(covmatrix)
$values
[1] 14 3
$vectors
[,1] [,2]
[1,] 0.9805807 -0.4472136
[2,] 0.1961161 0.8944272
Related
Given a random matrix (any size!), write a function that determines whether or not that matrix is a Toeplitz Matrix. In linear algebra, a Toeplitz matrix is one in which the elements on any given diagonal from top left to bottom right are identical.
Here is an example:
x <- structure(c(1, 5, 4, 7, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 8,
4, 3, 2), .Dim = 4:5)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 8
[2,] 5 1 2 3 4
[3,] 4 5 1 2 3
[4,] 7 4 5 1 2
So our function should receive such matrix and return TRUE if it meets the conditions.
To test the function, one can use stats::toeplitz() to generate a toeplitz matrix. So for example, the expected output of our function should be:
> toeplitz_detector(stats::toeplitz(sample(5, 5)))
> [1] TRUE
I've solved the problem by defining the following function:
toeplitz_solver <- function(a) {
# re-order a backwards, because we need to check diagonals from top-left
# to bottom right. if we don't reorder, we'll end up with top-right to
# bottom-left.
a <- a[, ncol(a):1]
# get all i and j (coordinates for every element)
i <- 1:nrow(a)
j <- 1:ncol(a)
# get all combinations of i and j
diags <- expand.grid(i, j)
# the coordinates for the diagonals are the ones where
# the sum is the same, e.g.: (3,2), (4,1), (2,3), (1,4)
sums <- apply(diags, 1, sum)
indexes <- lapply(unique(sums), function(x) {
diags[which(sums == x), ]
})
# indexes is now a list where every element is a list of coordinates
# the first element is a list for every coordinates for the first diag
# so on and so forth
results <- sapply(indexes, function(x) {
y <- a[as.matrix(x)]
return(all(y == y[1]))
})
# if every diagonal meets the condition, it is safe to assume that the
# input matrix is in fact toeplitz.
return(all(results))
}
What are the default values for the arguments nrow and ncol in the function matrix in R?
In order words: By writing
matrix(c(1,2,3,4,5,6), ncol=2)
I can make the function matrix automatically calculate how many rows the resulting matrix will have, and the output will be
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
However, if I want ncol to be a positional argument in this function call and I simply remove ncol=, that is
matrix(c(1,2,3,4,5,6), 2)
the "2" is going to end up as the value of nrow and not as the value of ncol, and I will instead get the matrix
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
I can fix this by providing the function a value for nrow so that the 2 is pushed to its correct position, like so:
matrix(c(1,2,3,4,5,6), 3, 2)
and I will get the desired matrix again. I could also use this method of providing a value for nrow if I were using a keyword argument for ncol, but at the same time wanted to be clear and provide the nrow argument as well:
matrix(c(1,2,3,4,5,6), nrow=3, ncol=2)
But now matrix doesn't calculate the number of rows for me, but I have to calculate it myself. What value should I write instead of 3 if I want tell matrix to calculate the number of rows itself? I've tried replacing the 3 with NULL, None (usually works in cases like this in Python), and -1 but these all give me errors (and 0 and 1 give me matrices with 0 rows and 1 row, respectively).
We can place a , before
matrix(c(1,2,3,4,5,6), ,2)
Here, the , is placed based on the argument order in the function. If we check ?matrix, the usage is
matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
Note, that most of the argument have default values. It is always better to pass function argument with names, but if we want to skip, can use the right number of , (also depends on the function behavior). Here, we can set the dimnames as well after skipping the byrow argument with a ,
matrix(c(1,2,3,4,5,6), ,2, ,list(NULL, c('a', 'b')))
# a b
#[1,] 1 4
#[2,] 2 5
#[3,] 3 6
how can I take exp() of each element in a matrix? I have mymatrix = matrix(c(2, 4, 3, 1, 5, 7), 3,2) and tried using res<-expm(mymatrix) but it requires mymatrix to be square. Is there another way to calculate each element so
res is matrix(c(exp(2), exp(4), exp(3), exp(1), exp(5), exp(7), 3,2) ?
res <- mymatrix
res [] <- exp(res)
> res
[,1] [,2]
[1,] 7.389056 2.718282
[2,] 54.598150 148.413159
[3,] 20.085537 1096.633158
Here you go.
I'm sure this is trivial - nonetheless, any help would be appreciated.
The problem is simple: given a matrix, I'd like to get TRUE if the matrix in question has at least one element equal to zero. So, checking
A <- matrix(c(1, 2, 3, 4, 5, 0), nrow = 2, ncol = 3, byrow = TRUE)
> A
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 0
would return TRUE, while
B <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3, byrow = TRUE)
> B
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
would return FALSE.
Something like
if ( A == 0 ) { cat("\nZero detected")}
gives a warning. Is there a simple way to do this?
The warning is generated because you're presenting a vector of logical to if, which expects a single value. any is a function to tell if any of the logical values are TRUE:
any(A==0)
## [1] TRUE
any(B==0)
## [1] FALSE
There's also a function all which determines if all of the values in a logical vector are TRUE.
Try
0 %in% A
It should return TRUE or FALSE. It works for NA too:
x = matrix(1:24, ncol = 4)
x[3, 3] = NA
NA %in% x
#TRUE
Is there any way in R, other than with loops, to create a matrix using different means and standard deviations for the matrix's columns?
For example, I want to create a 3x4 matrix representing 3 points with 4 attributes each, such that every column (every attribute) has its own mean and sd.
Yes, you can do without loops. Take advantage of the fact that matrices in R are stored in column-major order, and replicate the mean and sd vectors to match.
means <- c(1, 10, 100, 1000)
sds <- c(0.1, 1, 10, 100)
rows <- 3
cols <- 4
m <- matrix(rnorm(rows*cols, m=rep(means, each=rows), s=rep(sds, each=rows)),
rows, cols)
m
[,1] [,2] [,3] [,4]
[1,] 0.9993278 11.694798 105.53191 841.2182
[2,] 0.8945916 9.556729 92.90462 1212.6817
[3,] 0.9889313 10.088022 113.67009 991.2138
I am not sure what you are looking for but this might help:
matrix(c(x = rnorm(n=3,mean=0.5,1),
y = rnorm(n=3,mean=2, 4),
z = rnorm(n=3, mean=3.5, 10),
a= rnorm(n=3,mean=5,12)),nrow=3,ncol=4)
[,1] [,2] [,3] [,4]
[1,] 0.7876793 2.9456827 8.082376 -3.065875
[2,] -0.9956971 4.2766553 14.178532 -5.003888
[3,] 2.1224071 0.7110594 6.744876 -11.006110
Note: you might bet different results as the data is randomly generated. Each column has its own mean and standard deviation.