繁体   English   中英

从 R 中的数据帧创建相关矩阵

[英]Creating a correlation matrix from a data frame in R

我有一个相关性数据框,看起来像这样(尽管我的真实数据中有大约 15,000 行)

phen1<-c("A","B","C")
phen2<-c("B","C","A")
cors<-c(0.3,0.7,0.8)

data<-as.data.frame(cbind(phen1, phen2, cors))

    phen1  phen2   cors
1     A      B      0.3
2     B      C      0.7
3     C      A      0.8

这是在外部创建并读入 R 中,我想将此数据框转换为相关矩阵,其中 phen1 和 2 作为该矩阵的行和列的标签。 我只为下三角形或上三角形计算过这个,我没有对角线的 1。 所以我希望最终结果是一个完整的相关矩阵,但第一步可能是创建下/上三角形,然后转换为我认为的完整矩阵。 我不确定如何做这一步。

此外,结果可能不是直观的顺序,但我不确定这是否重要,但理想情况下我想要一种方法来做到这一点,它使用 phen1 和 phen 2 中的标签来确保矩阵具有正确的值在正确的地方,如果这有意义吗?

基本上为此,我想要这样的结果作为最终结果:

  A    B    C
A 1    0.3  0.8
B 0.3  1    0.7
C 0.8  0.7  1

我认为必须有一种优雅的方式来做到这一点,但是,这里有一个dplyrtidyr可能性:

data %>%
 spread(phen1, cors) %>%
 rename(phen = "phen2") %>%
 bind_rows(data %>%
            spread(phen2, cors) %>%
            rename(phen = "phen1")) %>%
 group_by(phen) %>%
 summarise_all(~ ifelse(all(is.na(.)), 1, first(na.omit(.))))

  phen      A     B     C
  <chr> <dbl> <dbl> <dbl>
1 A       1     0.3   0.8
2 B       0.3   1     0.7
3 C       0.8   0.7   1  

这是 base R 中的另一个,我们创建了一个与data相同的对称数据帧,但列倒置为phen1phen2 然后我们使用xtabs得到一个相关矩阵并将对角线设置为 1。

data1 <- data.frame(phen1 = data$phen2, phen2 = data$phen1, cors = data$cors)  
df <- rbind(data, data1)
df1 <- as.data.frame.matrix(xtabs(cors ~ ., df))
diag(df1) <- 1
df1

#    A   B   C
#A 1.0 0.3 0.8
#B 0.3 1.0 0.7
#C 0.8 0.7 1.0

数据

phen1<-c("A","B","C")
phen2<-c("B","C","A")
cors<-c(0.3,0.7,0.8)
data<- data.frame(phen1, phen2, cors)

您可以为此使用 Matrix 包。 您拥有的是数据的稀疏表示,并且您希望将其转换为密集(冗余)矩阵。

data <- data.frame(phen1, phen2, cors)

inds <- cbind(as.integer(data$phen1), as.integer(data$phen2))
inds <- t(apply(inds, 1, sort))

library(Matrix)
res <- sparseMatrix(i = inds[,1], 
             j = inds[,2], 
             x = data$cors,
             symmetric = TRUE)
#3 x 3 sparse Matrix of class "dsCMatrix"
#
#[1,] .   0.3 0.8
#[2,] 0.3 .   0.7
#[3,] 0.8 0.7 . 

res <- as.matrix(res)
diag(res) <- 1
dimnames(res) <- list(sort(data$phen1), sort(data$phen2))
res
#    A   B   C
#A 1.0 0.3 0.8
#B 0.3 1.0 0.7
#C 0.8 0.7 1.0

这是另一种选择。

首先将数据从 long 重新整形为 Wide 并转换为matrix 你有不同的选择来做到这一点( reshape2tidyr等); 在这里我使用tidyr::spread

library(tidyverse)
mat <- data %>% spread(phen2, cors) %>% column_to_rownames("phen1") %>% as.matrix()

然后我们分别从上三角矩阵和下三角矩阵填充缺失的NA值,并用1填充对角线。

mat[lower.tri(mat)] <- mapply(sum, mat[lower.tri(mat)], mat[upper.tri(mat)], na.rm = T)
mat[upper.tri(mat)] <- mat[lower.tri(mat)]
diag(mat) <- 1
mat
#    A   B   C
#A 1.0 0.3 0.8
#B 0.3 1.0 0.7
#C 0.8 0.7 1.0

您可以使用重塑库。

library(reshape)
data <- melt(data)
your_mat <- cast(data, phen1 ~ phen2 )

输出:

  phen1    A    B    C
1     A <NA>  0.3 <NA>
2     B <NA> <NA>  0.7
3     C  0.8 <NA> <NA>

您将 NA 的原因是因为您的输入表中缺少许多组合。 为了避免这种情况,您需要一个这样的输入表:

  phen1 phen2 cors
1     A     B  0.3
2     B     C  0.7
3     C     A  0.8
4     A     C  0.8
5     B     A  0.3
6     C     B  0.7
7     A     A  1.0
8     B     B  1.0
9     C     C  1.0

已经有很多解决方案,但我会以另一种方式提出。 注意:我正在设置数据,以便cors是数字而不是原始数据框中的一个因素。

data <- data.frame(phen1, phen2, cors)

然后我们可以扩展缺少组合的数据框,然后使用reshape2::acast()将数据转换为宽格式。

library(tidyverse)
library(reshape2)

data %>% 
  select(phen1 = phen2, phen2 = phen1, cors) %>%
  bind_rows(data) %>%
  acast(phen1 ~ phen2, fill = 1)

acast可以acast地让您用一些其他指定值填充缺失值,在本例中为 1。

另外,查看corrr包,它可能可以更巧妙地做到这一点。

这是我写的一个函数:

long2cormat <- function(xlong, x = "x", y = "y", r = "r") {
    # Takes some inspiration from https://stackoverflow.com/a/57904948/180892
    xlong <- xlong[,c(x, y, r)]
    names(xlong) <- c("x", "y", "r")
    
    data1 <- data.frame(x = xlong$x, y = xlong$y, r = xlong$r)    
    data2 <- data.frame(x = xlong$y, y = xlong$x, r = xlong$r)  
    df <- rbind(data1, data2)
    
    uv <- unique(c(df$x, df$y))
    df1 <- matrix(NA, nrow = length(uv), ncol = length(uv), dimnames = list(uv, uv))
    for (i in seq(nrow(df))) df1[df$x[i], df$y[i]] <- df$r[i]
    diag(df1) <- 1
    df1
}

要运行它,请执行以下操作:

xlong <- data.frame(phen1 = c("A","B","C"),
    phen2 = c("B","C","A"),
    cors = c(0.3,0.7,0.8))
long2cormat(xlong, "phen1", "phen2", "cors")

重要的是,对于我自己的用例,它将缺失的相关性保留为 NA。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM