Reputation: 57
How to use apply() function in r on iris dataset (a 3-d array dataset) to compute covariance matrices of the variables Sepal Length, Sepal Width, Petal Length, and Petal Width for each of the three species Setosa, Versicolor, and Virginica, expressed as a 3-d array.
Here are the top 6 rows of the dataset
, , Setosa
Sepal L. Sepal W. Petal L. Petal W.
[1,] 5.1 3.5 1.4 0.2
[2,] 4.9 3.0 1.4 0.2
[3,] 4.7 3.2 1.3 0.2
[4,] 4.6 3.1 1.5 0.2
[5,] 5.0 3.6 1.4 0.2
[6,] 5.4 3.9 1.7 0.4
, , Versicolor
Sepal L. Sepal W. Petal L. Petal W.
[1,] 7.0 3.2 4.7 1.4
[2,] 6.4 3.2 4.5 1.5
[3,] 6.9 3.1 4.9 1.5
[4,] 5.5 2.3 4.0 1.3
[5,] 6.5 2.8 4.6 1.5
[6,] 5.7 2.8 4.5 1.3
, , Virginica
Sepal L. Sepal W. Petal L. Petal W.
[1,] 6.3 3.3 6.0 2.5
[2,] 5.8 2.7 5.1 1.9
[3,] 7.1 3.0 5.9 2.1
[4,] 6.3 2.9 5.6 1.8
[5,] 6.5 3.0 5.8 2.2
[6,] 7.6 3.0 6.6 2.1
Upvotes: 1
Views: 240
Reputation: 3888
this can be achieved by iterating over the order of the last dimension, as lapply
by default loops over all the items:
lapply(1:dim(arr)[3], function(i) cov(arr[,,i]))
[[1]]
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 0.12424898 0.099216327 0.016355102 0.010330612
Sepal.Width 0.09921633 0.143689796 0.011697959 0.009297959
Petal.Length 0.01635510 0.011697959 0.030159184 0.006069388
Petal.Width 0.01033061 0.009297959 0.006069388 0.011106122
[[2]]
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 0.26643265 0.08518367 0.18289796 0.05577959
Sepal.Width 0.08518367 0.09846939 0.08265306 0.04120408
Petal.Length 0.18289796 0.08265306 0.22081633 0.07310204
Petal.Width 0.05577959 0.04120408 0.07310204 0.03910612
[[3]]
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 0.40434286 0.09376327 0.30328980 0.04909388
Sepal.Width 0.09376327 0.10400408 0.07137959 0.04762857
Petal.Length 0.30328980 0.07137959 0.30458776 0.04882449
Petal.Width 0.04909388 0.04762857 0.04882449 0.07543265
If you want the output to be a 3-d array
sapply(1:dim(arr)[3], function(i) cov(arr[,,i]), simplify="array") -> covar
, , 1
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 0.12424898 0.099216327 0.016355102 0.010330612
Sepal.Width 0.09921633 0.143689796 0.011697959 0.009297959
Petal.Length 0.01635510 0.011697959 0.030159184 0.006069388
Petal.Width 0.01033061 0.009297959 0.006069388 0.011106122
, , 2
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 0.26643265 0.08518367 0.18289796 0.05577959
Sepal.Width 0.08518367 0.09846939 0.08265306 0.04120408
Petal.Length 0.18289796 0.08265306 0.22081633 0.07310204
Petal.Width 0.05577959 0.04120408 0.07310204 0.03910612
, , 3
Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length 0.40434286 0.09376327 0.30328980 0.04909388
Sepal.Width 0.09376327 0.10400408 0.07137959 0.04762857
Petal.Length 0.30328980 0.07137959 0.30458776 0.04882449
Petal.Width 0.04909388 0.04762857 0.04882449 0.07543265
# if you want to add names
dimnames(covar)[3] <- dimnames(arr)[3]
Or following @G.Grothendieck 's comment
array(apply(arr, 3, var), dim(arr)[c(2, 2, 3)], dimnames(arr)[c(2, 2, 3)])
simplify2array(by(iris[-5], iris$Species, as.matrix)) -> arr
Upvotes: 2