Apply function in matrix elements of a list in R

74 Views Asked by At

I have a list of elements in R as follows:

set.seed(123)
A <- matrix(rnorm(20 * 20, mean = 0, sd = 1), 20, 20)
B <- matrix(rnorm(20 * 20, mean = 0, sd = 1), 20, 20)
C <- matrix(rnorm(20 * 20, mean = 0, sd = 1), 20, 20)
D <- matrix(rnorm(20 * 20, mean = 0, sd = 1), 20, 20)
E <- matrix(rnorm(20 * 20, mean = 0, sd = 1), 20, 20)

DATA <- list(A,B,C,D,E)

I want for each matrix (A,B,...,E) to find the eigenvalues and combine them in a data frame as follows:

ei1 <- eigen(DATA[[1]])
ei1 <- round(ei1$values, 2)
eigenvalues1 <- as.data.frame(ei1)

ei2 <- eigen(DATA[[2]])
ei2 <- round(ei2$values, 2)
eigenvalues2 <- as.data.frame(ei2)

ei3 <- eigen(DATA[[3]])
ei3 <- round(ei3$values, 2)
eigenvalues3 <- as.data.frame(ei3)

ei4 <- eigen(DATA[[4]])
ei4 <- round(ei4$values, 2)
eigenvalues4 <- as.data.frame(ei4)

ei5 <- eigen(DATA[[5]])
ei5 <- round(ei5$values, 2)
eigenvalues5 <- as.data.frame(ei5)

eigenavules <-
  cbind(eigenvalues1,eigenvalues2,eigenvalues3,eigenvalues4,eigenvalues5
  )

How can I make this procedure automatically with the apply (or similar) function in instead of manually like above?

2

There are 2 best solutions below

0
akrun On BEST ANSWER

We may use lapply to loop over the list and apply the function, extract the eigen values and then do the conversion to data.frame at the end

eigenvalues <- as.data.frame(do.call(cbind,
      lapply(DATA, function(x) round(eigen(x)$values, 2))))

-output

> eigenvalues
            V1          V2          V3          V4          V5
1   1.77+3.73i  5.33+0.00i  5.11+0.00i -2.52+3.53i -1.87+4.42i
2   1.77-3.73i  1.72+4.13i -5.08+0.00i -2.52-3.53i -1.87-4.42i
3  -0.50+3.97i  1.72-4.13i  2.41+3.87i  2.12+3.32i  2.96+3.44i
4  -0.50-3.97i -4.02+1.85i  2.41-3.87i  2.12-3.32i  2.96-3.44i
5  -3.38+2.06i -4.02-1.85i -2.60+3.46i  3.72+0.00i -4.15+0.00i
6  -3.38-2.06i -3.27+0.00i -2.60-3.46i -3.16+0.30i  1.67+3.35i
7   3.89+0.00i  1.48+2.89i  0.10+3.78i -3.16-0.30i  1.67-3.35i
8  -2.47+3.00i  1.48-2.89i  0.10-3.78i  2.50+1.89i  3.28+1.47i
9  -2.47-3.00i  3.05+0.00i  3.74+0.00i  2.50-1.89i  3.28-1.47i
10  3.51+0.00i -0.97+2.79i  2.38+2.10i -2.69+1.46i -2.88+1.40i
11  2.04+2.29i -0.97-2.79i  2.38-2.10i -2.69-1.46i -2.88-1.40i
12  2.04-2.29i -1.86+2.07i -2.44+0.01i -1.04+2.51i -1.32+2.89i
13 -3.03+0.00i -1.86-2.07i -2.44-0.01i -1.04-2.51i -1.32-2.89i
14 -1.97+1.67i -2.18+0.00i -1.52+1.78i  0.69+2.32i -0.77+2.12i
15 -1.97-1.67i  2.14+0.00i -1.52-1.78i  0.69-2.32i -0.77-2.12i
16  0.81+1.91i  1.61+0.77i  1.93+0.86i  2.23+0.85i  1.40+1.09i
17  0.81-1.91i  1.61-0.77i  1.93-0.86i  2.23-0.85i  1.40-1.09i
18  1.02+0.00i  0.14+1.55i -0.04+1.88i -0.77+0.57i  0.65+0.35i
19 -0.57+0.47i  0.14-1.55i -0.04-1.88i -0.77-0.57i  0.65-0.35i
20 -0.57-0.47i -0.99+0.00i  0.26+0.00i  0.67+0.00i  0.58+0.00i
0
guero64 On

Not quite what you are looking for, but maybe:

df <- NULL
for (i in length(DATA)) {
  di <- as.data.frame(round(eigen(DATA[[i]])$values,2))
  df <- if (is.null(df)) di else cbind(df,di)
}