2017-01-22 46 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