微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将虚拟编码矩阵转换为邻接矩阵

如何解决将虚拟编码矩阵转换为邻接矩阵

大家,我有这个二元矩阵

rownames <- c("gene1","gene2","gene3","gene4")
colnames <- c("A","B","C","D")

data <- matrix(c(1,1,1),nrow = 4,ncol = 4,byrow = TRUE,dimnames = list(rownames,colnames))

data
#      A B C D
#gene1 1 0 1 0
#gene2 1 1 0 0
#gene3 1 0 1 0
#gene4 0 1 0 1

我想将数据转化为这个邻接矩阵,用于网络 igraph 可视化。

   A B C D
A  0 1 2 0
B  1 0 0 1
C  2 0 0 0
D  0 1 0 0

说明:从 A 中,gene2 与 B 共享分数“1”,这就是为什么我得到 1 分。 从A,gene1和gene3与C共享分数“total 2”,这就是为什么它得到2分

可以把矩阵改成这个吗?我应该使用迭代吗?但我不知道。 Tidyverse 方法将非常有帮助。

谢谢

解决方法

您可以使用 outer 函数。

count1s <- function(x,y) colSums(x == 1 & y == 1)
n <- 1:ncol(data)
mat <- outer(n,n,function(x,y) count1s(data[,x],data[,y]))
diag(mat) <- 0
dimnames(mat) <- list(colnames(data),colnames(data))
mat

#  A B C D
#A 0 1 2 0
#B 1 0 0 1
#C 2 0 0 0
#D 0 1 0 0
,

一个 tidyverse 方法 - 欢迎任何关于使其更简洁的反馈

library(tidyverse)

data_tibble <- as_tibble(data)
calculate_adjacency <- function(data,col_name) {
  column_names <- names(data)
  data %>%
    filter(!!sym(col_name) ==1) %>%
    select(!matches(col_name)) %>%
    pivot_longer(cols = everything(),names_to = "name",values_to = "value") %>%
    group_by(name) %>%
    summarize(value = sum(value)) %>%
    pivot_wider(names_from = name,values_from = value) %>%
    mutate("{col_name}" := 0) %>%
    select(all_of(column_names))
}

map_df(colnames(data_tibble),calculate_adjacency,data = data_tibble) %>%
  mutate(key = colnames(.)) %>%
  relocate(key,.before = 1)

# A tibble: 4 x 5
  key       A     B     C     D
  <chr> <dbl> <dbl> <dbl> <dbl>
1 A         0     1     2     0
2 B         1     0     0     1
3 C         2     0     0     0
4 D         0     1     0     0
,

更简单的 tidyverse 方法

data2 <- as.data.frame(data) %>% rownames_to_column("id") %>%
  pivot_longer(cols = -id) %>% filter(value != 0)

merge(data2,data2,by = "id",all = T) %>%
  filter(name.x != name.y) %>%
  group_by(name.x,name.y) %>%
  summarise(val = n()) %>%
  pivot_wider(names_from = name.y,values_from = val,values_fill = 0,names_sort = T) %>%
  column_to_rownames("name.x")

  A B C D
A 0 1 2 0
B 1 0 0 1
C 2 0 0 0
D 0 1 0 0

更简单的方法是

data2 <- as.data.frame(data) %>% rownames_to_column("id") %>%
  pivot_longer(cols = -id) %>% filter(value != 0)

inter <- crossprod(xtabs(~id+name,data2),xtabs(~id+name,data2))
diag(inter) <- 0
inter

    name
name A B C D
   A 0 1 2 0
   B 1 0 0 1
   C 2 0 0 0
   D 0 1 0 0

在链接最简单的问题后我意识到

inter <- crossprod(data)
diag(inter) <- 0
inter
  A B C D
A 0 1 2 0
B 1 0 0 1
C 2 0 0 0
D 0 1 0 0

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。