Home > Net >  Apply function in matrix elements of a list in R
Apply function in matrix elements of a list in R

Time:08-05

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?

CodePudding user response:

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

CodePudding user response:

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)
}
  • Related