2017-01-22 51 views
1

我想計算每個物種(bac)與第二個數據幀中每個因子(fac)的相關性和p值。兩者都在相同數量的臺站上測量,但是bac和fac的數量不匹配。兩個矩陣的所有行的所有組合的相關性/ p值

bac1 <- c(1,2,3,4,5) 
bac2 <- c(2,3,4,5,1) 
bac3 <- c(4,5,1,2,3) 
bac4 <- c(5,1,2,3,4) 
bac <- as.data.frame(cbind(bac1, bac2, bac3, bac4)) 
colnames(bac) <- c("station1", "station2", "station3", "station4") 
rownames(bac) <- c("bac1", "bac2", "bac3", "bac4", "bac5") 

fac1 <- c(1,2,3,4,5,6) 
fac2 <- c(2,3,4,5,1,6) 
fac3<- c(3,4,5,1,2,6) 
fac4<- c(4,5,1,2,3, 6) 
fac <- as.data.frame(cbind(fac1, fac2, fac3, fac4)) 
colnames(fac) <- c("station1", "station2", "station3", "station4") 
rownames(fac) <- c("fac1", "fac2", "fac3", "fac4", "fac5", "fac6") 

我想象的結果有些看起來像這樣,維持地方的名字就知道是哪個呈現組合:

bac1-fac1 cor1 p1 
bac1-fac2 cor2 p2 
bac1-fac3 cor3 p3 

bac2-fac1 corx px... 

我已經看過從Hmist功能rcorr和corr.test從鬥志,但無法找到一個必要的行排列的例子...任何想法?

回答

3

,這樣你配對計算列之間的相關性,這將是超級容易。

tbac <- data.frame(t(bac)) 
tfac <- data.frame(t(fac)) 

f <- function (x, y) cor(x, y) 

tab <- outer(tfac, tbac, Vectorize(f)) 

as.data.frame.table(tab) 

我有一個答案使用相同的想法:Match data and count number of same value

+0

這樣做非常緊湊。一如既往的偉大答案! – akrun

+0

我不記得了,但感謝分享那一個。 – akrun

+1

謝謝,這似乎工作得很好!我想知道爲什麼與fac6有任何相關性產生了NA,但計算出來(所有值都是6)。 – Helena

1

我們可以使用expand.gridapply指定MARGIN爲1獲得的「BAC」和「FAC」,遍歷行rownames組合,子集基礎上,rownames「BAC」和「FAC」的行,做corr.test,如果你調整你的數據中提取的「p」值作爲list

library(psych) 
do.call(c, apply(expand.grid(rownames(bac), rownames(fac)), 1, 
    function(x) list(corr.test(cbind(unlist(bac[1,]), unlist(fac[1,])))$p))) 
+0

@李哲源ZheyuanLi它讓你看到其他一些參數,如'list'中的welll。我認爲'rcorr'也做類似的事情從'Hmisc' – akrun

+0

我最近發現expand.grid,我真的很喜歡它。但我嘗試你的解決方案,輸出似乎不正確...我沒有任何行/列名? – Helena

1

可以剛過expand.grid

pairs <- as.matrix(expand.grid(1:nrow(bac),1:nrow(fac))) 
pairs <- cbind(pairs,NA,NA) 
b <- as.matrix(bac) 
f <- as.matrix(fac) 
for(i in 1:nrow(pairs)){ 
    pairs[i,3] <- cor(b[pairs[i,1],], f[pairs[i,2],]) 
    pairs[i,4] <- cor.test(b[pairs[i,1],], f[pairs[i,2],])$p.value 
} 
colnames(pairs) <- c('bac','fac','corr','p') 
pairs 
##  bac fac  corr   p 
## [1,] 1 1 0.98994949 0.01005051 
## [2,] 2 1 -0.07559289 0.92440711 
## [3,] 3 1 -0.60000000 0.40000000 
## [4,] 4 1 -0.60000000 0.40000000 
## [5,] 5 1 -0.07559289 0.92440711 
## [6,] 1 2 0.98994949 0.01005051 

的行中循環。如果你想要的名字,那麼你可以做

pairs <- as.data.frame(pairs) 
pairs[,1] <- sapply(pairs[,1],function(x) rownames(bac)[x]) 
pairs[,2] <- sapply(pairs[,2],function(x) rownames(fac)[x]) 

雖然在這一點上,它可能更容易使用李哲源李宋哲元的解決方案。

+0

,也非常有幫助,但不保留原來的名字,這將有助於我的「真實」情況! – Helena

2

您可以將完整的矩陣傳遞給cor函數(或psych::corr.test),它負責查找相關列的相關性。

例如

cor(t(fac), t(bac)) 
#   bac1  bac2  bac3  bac4  bac5 
# fac1 0.9899495 -0.07559289 -0.60000000 -0.60000000 -0.07559289 
# fac2 0.9899495 -0.07559289 -0.60000000 -0.60000000 -0.07559289 
# fac3 -0.3207135 0.94285714 -0.07559289 -0.07559289 -0.48571429 
# fac4 -0.8000000 -0.32071349 0.98994949 0.98994949 -0.32071349 
# fac5 -0.3207135 -0.48571429 -0.07559289 -0.07559289 0.94285714 
# fac6   NA   NA   NA   NA   NA 

您可以使用reshape2::melt

reshape2::melt(cor(t(fac), t(bac))) 
# Var1 Var2  value 
# 1 fac1 bac1 0.98994949 
# 2 fac2 bac1 0.98994949 
# 3 fac3 bac1 -0.32071349 
# 4 fac4 bac1 -0.80000000 
# --- 
# --- 

然後把這個長格式要獲得p值使用相同的方法

test <- psych::corr.test(t(fac), t(bac), adjust="none") 

和熔體像以前一樣加入

merge(melt(test$r, value.name="cor"), melt(test$p, value.name="p-value"), by=c("Var1", "Var2")) 
# Var1 Var2   cor p-value 
# 1 fac1 bac1 0.98994949 0.01005051 
# 2 fac1 bac2 -0.07559289 0.92440711 
# 3 fac1 bac3 -0.60000000 0.40000000 
# 4 fac1 bac4 -0.60000000 0.40000000 
# 5 fac1 bac5 -0.07559289 0.92440711 
# 6 fac2 bac1 0.98994949 0.01005051 
+1

這是一個不錯的選擇。我錯過了轉置部分。 – akrun

+1

謝謝Akrun ... – user20650