2016-10-29 26 views
5

Mam zestaw danych 9 próbek (wierszy) z 51608 zmiennymi (kolumnami) i ciągle otrzymuję błąd za każdym razem, gdy próbuję zmienić skalę to:Jak rozwiązać prcomp.default(): nie można przeskalować kolumny stałej/zera do wariancji jednostki

działa to dobrze

pca = prcomp(pca_data) 

jednak

pca = prcomp(pca_data, scale = T) 

daje

> Error in prcomp.default(pca_data, center = T, scale = T) : 
    cannot rescale a constant/zero column to unit variance 

Oczywiście trochę trudniej jest zamieścić powtarzalny przykład. Jakieś pomysły na temat tego, czym może być umowa?

Szukam stałych kolumn:

sapply(1:ncol(pca_data), function(x){ 
       length = unique(pca_data[, x]) %>% length 
      }) %>% table 

wyjściowa:

. 
     2  3  4  5  6  7  8  9 
    3892 4189 2124 1783 1622 2078 5179 30741 

więc nie ma stałych kolumn. Podobnie jest z NA użytkownika -

is.na(pca_data) %>% sum 

    >[1] 0 

Działa to dobrze:

pca_data = scale(pca_data) 

Ale potem oboje wciąż daje dokładnie ten sam błąd:

pca = prcomp(pca_data) 
    pca = prcomp(pca_data, center = F, scale = F) 

Więc dlaczego nie mogę ja kieruję dostać skalowany PCA na tych danych? Ok, pozwala na 100% pewność, że nie jest stała.

pca_data = pca_data + rnorm(nrow(pca_data) * ncol(pca_data)) 

Identyczne błędy. Dane Numierc?

sapply(1:nrow(pca_data), function(row){ 
     sapply(1:ncol(pca_data), function(column){ 
     !is.numeric(pca_data[row, column]) 
     }) 
    }) %>% sum 

Nadal te same błędy. Nie mam pomysłów.

Edytuj: więcej i włamań przynajmniej do rozwiązania.

Później nadal problemy ze grupowanie tym danych np:

Error in hclust(d, method = "ward.D") : 
     NaN dissimilarity value in intermediate results. 

Przycinanie wartości poniżej pewnego cuttoff np < 1 do zera miał żadnego wpływu. Ostatecznie udało się przyciąć wszystkie kolumny, które miały więcej niż x zer w kolumnie. Przetworzono dla zer: < = 6, ale 7+ dało błędy. Nie mam pojęcia, czy to oznacza, że ​​jest to problem w ogóle, czy po prostu przydarzyło się problematyczne kolumny. Nadal byłby szczęśliwy, gdyby ktoś miał jakieś pomysły, dlaczego to powinno działać dobrze, o ile żadna zmienna nie jest zerowa (lub stała w inny sposób).

+0

Zobacz, co 'sum (! Is.finite (scale (pca_data))) daje. –

+0

Rozwiązałeś problem? – Joe

Odpowiedz

6

Nie sądzę, że szukasz poprawnie kolumn zerowej wariancji. Spróbujmy z pewnymi sztucznymi danymi. Po pierwsze, akceptowalna matryca: 10x100:

mat <- matrix(rnorm(1000, 0), nrow = 10) 

I jedna z kolumną zero-wariancji. Nazwijmy to oopsmat.

const <- rep(0.1,100) 
oopsmat <- cbind(const, mat) 

Pierwsze elementy oopsmat wyglądać następująco:

 const                        
[1,] 0.1 0.75048899 0.5997527 -0.151815650 0.01002536 0.6736613 -0.225324647 -0.64374844 -0.7879052 
[2,] 0.1 0.09143491 -0.8732389 -1.844355560 0.23682805 0.4353462 -0.0.61859245 0.5691021 
[3,] 0.1 -0.80649512 1.3929716 -1.438738923 -0.09881381 0.2504555 -0.857300053 -0.98528008 0.9816383 
[4,] 0.1 0.49174471 -0.8110623 -0.941413109 -0.70916436 1.3332522 0.003040624 0.29067871 -0.3752594 
[5,] 0.1 1.20068447 -0.9811222 0.928731706 -1.97469637 -1.1374734 0.661594937 2.96029102 0.6040814 

Spróbujmy skalowane i nieskalowany PCA na oopsmat:

PCs <- prcomp(oopsmat) #works 
PCs <- prcomp(oopsmat, scale. = T) #not forgetting the dot 
#Error in prcomp.default(oopsmat, scale. = T) : 
    #cannot rescale a constant/zero column to unit variance 

Ponieważ nie można podzielić przez odchylenie standardowe jeśli to nieskończoność. Aby zidentyfikować kolumnę zerowej wariancji, możemy użyć which w następujący sposób, aby uzyskać nazwę zmiennej.

which(apply(oopsmat, 2, var)==0) 
#const 
#1 

i usunięcia zerowe kolumny wariancji z zestawu danych, można użyć tego samego apply wyraz, wyznaczając odchylenie jest równe zeru.

oopsmat[ , apply(oopsmat, 2, var) != 0] 

Mam nadzieję, że dzięki temu sprawy staną się bardziej przejrzyste!