R попарно функция PCA покрывает X нечисловой c объект - PullRequest
1 голос
/ 21 марта 2020

Я пишу функцию, которая выполняет PCA для пар переменных в объекте xts, пока корреляция между всеми переменными не станет меньше 0,1. Вот функция, которую я написал:


PCA_Selection <- function(X, r=0.1){

  M <- cor(X) # Creating corrolation matrix 
  M[M==1] <- 0 # filling the diagnal with 0s so that pairs of the same variables are not considered 
  while(max(abs(M)) > r){
    M <- cor(X)
    PCA_vars <- matrix(,nrow = (nrow(M))^2 ,ncol = 2)
    for(i in 1:ncol(M)){ # Selects variables that will be use for PCA
      for(j in 1:nrow(M)){
        if(M[j,i] > r & M[j,i] < 1){
          PCA_vars[c(i*j),] <- c(row.names(M)[i],colnames(M)[j])
        }}} # works 
    PCA_vars <- na.omit(PCA_vars) # works 
    for (i in 1:nrow(PCA_vars)) {
      PCA_pre <- prcomp(X[,c(names(X) %in% PCA_vars[i,])]) 
      Sum_PCA <- summary(PCA_pre)
      tmp <- data.frame()
      if (Sum_PCA[["importance"]][2,1] > 0.95){ # if the first component captures 95% of variance
        tmp <- data.frame(predict(PCA_pre, X)[,1]) # then only use the first component for predictions 
        names(tmp) <- c(paste0("Com_",PCA_vars[i,1],"_",PCA_vars[i,2],"_1"))
      }else { # else use all both of the component and do not reduce the dimensions 
        tmp <- predict(PCA_pre,X)
        colnames(tmp) <- c(paste0("Com_",PCA_vars[i,1],"_",PCA_vars[i,2],"_1"), 
                        paste0("Com_",PCA_vars[i,1],"_",PCA_vars[i,2],"_2"))
      }
      Xnew <- cbind(X,tmp)
      X <- Xnew
    }

    PCA_vars <- unique(as.vector(PCA_vars)) # Variables to be removed 
    X <- X[, -which(colnames(X) %in% PCA_vars)]

    M <- cor(X)
    M[M==1] <- 0
  }  
    return(Xnew)
} 

Однако, когда я запускаю функцию, возвращается странная ошибка:

Error in colMeans(x, na.rm = TRUE): 'x' must be numeric 

Данные, с которыми я тестирую функцию, являются XTS объект, который не имеет каких-либо пропущенных наблюдений. Кроме того, все переменные имеют ненулевую дисперсию, и в данных есть только непрерывные числовые переменные c.

1 Ответ

0 голосов
/ 22 марта 2020

Ошибка возникает в строке 15: PCA_pre <- prcomp(X[,c(names(X) %in% PCA_vars[i,])])

На самом деле, это работает при первом запуске, когда i = 1. Но он завершается неудачно при втором запуске, когда i = 2 по следующей причине.

В строке 27 вы изменяете X, назначая его Xnew:

27: X <- Xnew

, что создано в строке 26:

26: `Xnew <- cbind(X,tmp)

, которую я не могу понять. В любом случае, tmp назначается в строке 19 (если главный компонент захватывает> 0,95 от общей дисперсии) или в строке 22 (если это не так).

19: tmp <- data.frame(predict(PCA_pre, X)[,1])
22: tmp <- predict(PCA_pre,X)

Это также сбивает с толку меня, потому что при строка 19 tmp будет иметь класс «data.frame», а строка 22 - класс «matrix». Это важно позже, когда вы создаете объект Xnew в строке 26 (см. Выше). Если tmp является фреймом данных, то Xnew будет «матрицей», у которой нет атрибута names:

names(X)
NULL

И вот почему вы получаете ошибку в строке 15 (см. Выше) ; функция prcomp пытается запустить PCA на пустом множестве.

Я думаю, что решение может заключаться в том, чтобы не использовать функцию data.frame () в строке 19.

19: tmp <- predict(PCA_pre, X)[,1]

Я проверил это на примере набора данных "xts", но, кажется, он работает вечно. Но, по крайней мере, ошибки нет.

И, кроме того, строка 17 может быть опущена, поскольку она, похоже, ничего не делает.

17: tmp <- data.frame()
...