2013-09-14 2 views
0

У меня есть набор данных с несколькими видами и около 400 переменных. Я хотел бы провести анализ компонентов (PCA) по каждому отдельному виду и вернуть переменную с наивысшим значением нагрузки для каждого вида.Многофакторный анализ PCA, извлекающий максимальные значения нагрузки

Чтобы сделать REPLICATE манекен набор моих данных:

set.seed(45) 
pcadata <- data.frame(matrix(sample(10, 26746*400, TRUE), ncol=400)) 
cbind(pcadata,"Species") 

Одна из проблем, я столкнулся это с различными размерами выборки для данного вида. Так, например, у меня могло бы быть 250 образцов видов A и 520 видов B. Поэтому я должен использовать функцию prcomp, потому что у меня больше переменных, чем у образцов. Поэтому, если виды А (SPA) были в data.frame, я бы сначала подмножество данных:

pcadata.s<-pcadata[,2:401] 

pca<-prcomp(pcadata.s,cor=T,scale=T) 
al<-abs(pca$rotation)     #Absolute value of the loading value 
loads<-sweep(al,2,colSums(al),"/")  #Percentage contribution 
loads.mtx<-as.data.frame(loads) 
rownames(loads.mtx)[apply(loads.mtx,2,which.max)] #Return the Column-name with the max value 

Я хотел бы, без необходимости подвыборки каждый раз, получить имена столбцов на каждый Виды группировок, например:

Species PC1  PC2  PC3  PC4  PC5 
spA  V3  V100  V287  V2  V65 
spB  V78 V197  V310  V23  V333 
........ 

Просто понял: мне нужно выбрать компоненты Я заинтересован в, предпочтительно 95% объясненной дисперсии, и, возможно, я буду стараться на 99% тоже ... но у меня будет чтобы включить код для этого.

Любые предложения будут оценены.

+0

Мой совет будет заключаться в том, чтобы ваш фиктивный набор немного меньше людей мог проверить проблему, не имея дело с вычислительной нагрузкой. Также 'cbind (pcadata,« Species »)' ничего не принесет, а вашим столбцам не будет имени вида. –

+0

@Manetheran, спасибо. Я хотел включить группировку видов только в качестве ссылки. Я не хотел отклоняться от основной проблемы, которая у меня есть, которая пытается получить требуемый вывод без необходимости подмножества вручную для каждой группы видов. Я опробовал свой код на очень маленьком фиктивном наборе, но я полностью понимаю ваши комментарии о том, как сохранить макет. Спасибо, очень признателен. – user2507608

ответ

1

Если вы сохраняете имя вида в качестве переменной в кадре данных, вы можете использовать ddply в пакете plyr.

library(plyr) 
# create data with a species variable 
set.seed(45) 
df <- data.frame(matrix(sample(1:10, size = 50, replace = TRUE), ncol = 5)) 
df$species <- rep(1:2, each = 5) 

# run pca and massage data per species 
df2 <- ddply(.data = df, .variables = .(species), function(x){ 
    pca <- prcomp(x[ , 1:5], cor = TRUE, scale = TRUE) 
    load <- abs(pca$rotation) 
    prop_load <- apply(load, 2, function(x) x/sum(x)) 
    max_load <- rownames(prop_load)[apply(prop_load, 2, function(x) which.max(x))] 
    max_load2 <- data.frame(t(max_load)) 
    names(max_load2) <- colnames(load) 
    return(max_load2) 
} 
) 
df2 

# species PC1 PC2 PC3 PC4 PC5 
# 1  1 X1 X2 X4 X3 X5 
# 2  2 X2 X1 X3 X2 X5 
+0

Спасибо Henrik, я обязательно посмотрю на пакет 'plyr'. Вы определенно сохранили мне некоторые строки кодирования. Очень признателен. – user2507608

+0

Мне очень жаль. Я НЕ ИДЕЯ, это было возможно. Примите мои самые скромные извинения и снова спасибо за это. – user2507608

+0

Привет, Henrik, я пытаюсь запустить эту функцию по моим данным (которая является числовой), но я продолжаю получать ошибку 'Ошибка в eval.quoted (.variables, data): envir должен быть либо NULL, либо список, либо «environment» или «Ошибка в if (empty (.data)) return (.данные): отсутствует значение, в котором требуется TRUE/FALSE '. Я искал преобразование числа в целое число, но он заменяет мои значения 0 и 1. Есть ли способ обойти это? – user2507608

1

Если я правильно понимаю вашу проблему, вы хотите применить функцию prcomp к подмножествам ваших данных. У меня нет собственного способа справиться с этим (что я знаю).

Вы могли бы попробовать что-то вдоль этих линий:

species <- unique(colnames(pcadata)) 
pcaresults <- list() 
for (sp in species) { 
    spIndices <- which(colnames(pcadata) == sp) 
    pcaresults[sp] <- prcomp(pcadata[,spIndices], cor=T,scale=T) 
} 

Это даст вам список, где каждый элемент является обратным результатом от СПС на этих видах. Вы можете изменить цикл или форматировать список возврата, чтобы получить только нужные данные.

+1

@ Manetheran, Спасибо миллион. Я обязательно отдам это. Ваш код помог мне понять, как использовать список в цикле, с этим я некоторое время борюсь. Спасибо за помощь. – user2507608

+0

Рад помочь! R может сбивать с толку вначале! –

Смежные вопросы