I was recently working with a repeated-measures dataset and needed to perform dimensionality reduction. After reviewing several online sources, I used the method suggested in the following blog posts (Computing principal components scores for new data with phyl.pca and Computing phylogenetic PCA scores for individual data). Breifly, the method involves the following steps:
- Mean aggregation: Aggregating the repeated measures by calculating the mean for each variable across time points, i.e., one row of observation per individual.
- Dimensionality reduction: Applying PCA on the aggregated data to obtain rotation matrices.
- Score calculation: Using the obtained rotations to calculate new scores for the full (non-aggregated) dataset.
Although the blog post focused specifically on phylogenetic PCA, I believe the concepts also apply to standard PCA. Additionally, the blog highlighted the distinction between performing PCA with a covariance matrix versus a correlation matrix. I opted to use the covariance matrix, which I understand is generally preferred when the data have been scaled prior to conducting PCA.
Here’s a simplified demonstration of my approach:
data(iris) # for demonstration purposes, I assumed that each category of "Species" represents a unique individual
a <- aggregate(Sepal.Length ~ Species, iris, mean)
b <- aggregate(Sepal.Width ~ Species, iris, mean)
c <- aggregate(Petal.Length ~ Species, iris, mean)
d <- aggregate(Petal.Width ~ Species, iris, mean)
iris_agg <- merge(merge(merge(a,b,"Species"),c,"Species"),d,"Species")
iris_agg[-1] <- lapply(iris_agg[-1], function(x) {x <- as.vector(scale(x)); return(x)}) # I scaled all my variables before performing PCA
iris_agg_pca <- prcomp(iris_agg[-1], center = FALSE, scale. = FALSE)
iris[-5] <- lapply(iris[-5], function(x) {x <- as.vector(scale(x)); return(x)})
data <- as.matrix(iris[-5]) # droppingdropped "Species"non-numeric variable
ev <- as.matrix(iris_agg_pca$rotation)
result <- data %*% ev
While I believe this approach is valid (correct me if you don't think so), I have some concerns:
- Unequal time points: My dataset contained individuals measured at different numbers of time points, and I’m unsure if this method was able to appropriately handle that.
- Inclusion of categorical variables: In my dataset, all categorical variables had only two levels. I simply encoded the categorical variables as zeros and ones, but I’m unsure if this was appropriate.
I’d appreciate any insights or suggestions for addressing these concerns, including other alternative approaches for mitigating my concerns.