2017-11-29 8 views
0

에 대한 방향성 소스 대상 형식으로 그룹화 된 데이터 나는이 데이터 집합이 있습니다R : 네트워크 시각화

test.set <- read.table(text = " 
          cluster.id letters cat 
         1   5  A  pink 
         2   4  B  blue 
         3   4  B  blue 
         4   3  A  pink 
         5   3  E  pink 
         6   3  D  pink 
         7   3  C  pink 
         8   2  A  blue 
         9   2  E  blue 
         10   1  A  green 
         11   0  A  pink 
         12   0  E  pink", header = T, stringsAsFactors = F) 

내가 편지가 무엇을 클러스터에 함께 결국 그들이 속한 cat 기억하는 관심이 있어요.

> 1 이상의 고유 문자가 포함 된 클러스터 만 관련됩니다 (예 : 클러스터 4는 문자 B 만 포함하므로 관련 없음). 의 첫 번째 적어도 두 가지 문자가 모든 클러스터를 걸러 보자

x <- test.set %>% group_by(cluster.id) %>% 
     mutate(letter.count = n_distinct(letters)) %>% 
     filter(letter.count > 1) %>% 
     ungroup() 



     cluster.id letters cat letter.count 
     <int> <chr> <chr>  <int> 
1   3  A pink   4 
2   3  E pink   4 
3   3  D pink   4 
4   3  C pink   4 
5   2  A blue   2 
6   2  E blue   2 
7   0  A pink   2 
8   0  E pink   2 

그런 다음 나는이에서 소스 목표 매트릭스/데이터 프레임을 구축하고자합니다. 결과 네트워크는 무향 네트워크이므로 A - E (E - A는 포함하지 않음)와 같은 관계 만 원합니다.

source target weight cat 

A E 2 pink 
A E 1 blue 
A D 1 pink 
A C 1 pink 
E D 1 pink 
E C 1 pink 
D C 1 pink 

나는이 작업을 수행하는 라이브러리 (또는 정말 간단한 트릭)이 있음을 확신하지만, :) (I 손으로 제대로 일을하는 경우)이 다음 소스/대상 매트릭스가 발생합니다 나는 그것을 이해할 수 없다. 이 모든 스마트/간단한 방법?


반 의사 예 : 의견

@Clarinetist

# for each cluster in test_set 
# get all unique pairwise combinations for the letters: 
combinations = unique(expand.grid(letters,letters)) %>% 
    filter(.$Var1 != .$Var2) #removes self,self combinations 
combinations = combinations[!duplicated(apply(combinations,1,function(x) paste(sort(x),collapse=''))),] 
# check whether the letter combination + cat is already in the data frame 
# if not add it with weight = 1 (e.g. source: A, target: E, weight: 1, cat: pink) 
# else increase the weight by 1 (e.g. source:A, target: E, weigth + 1, cat: pink) 

반응은 어쩌면 내가 분명하지 않다 그러나 당신의 코드는 버그가 포함되어 있습니다.

txt <- "cluster.id\tletters\tcat 
10283\tklebsiella pneumoniae\tprotein1 
10463\tescherichia coli\tundefined 
10463\tmycobacterium tuberculosis\tundefined 
10469\tescherichia coli\tundefined 
10469\tmycobacterium tuberculosis\tundefined" 

txt <- "cluster.id\tletters\tcat 
10283\tklebsiella pneumoniae\tprotein1 
10463\tescherichia coli\tundefined 
10463\tmycobacterium tuberculosis\tundefined 
10\tescherichia coli\tundefined 
10\tmycobacterium tuberculosis\tundefined" 

은 첫 번째 잘 작동 :

# A tibble: 1 x 4 
      source      target   cat weight 
      <fctr>      <fctr>   <chr> <dbl> 
1 escherichia coli mycobacterium tuberculosis 1046undefined  2 

동일한 결과를 생성한다 두번째는 (I 만에 10,469에서 ID를 변경

(여전히 그 수는 1046 이상이다) 10). 그러나 잘못된 결과가 나타납니다.

# A tibble: 2 x 4 
      source      target   cat weight 
      <fctr>      <fctr>   <chr> <dbl> 
1 escherichia coli mycobacterium tuberculosis 1046undefined  1 
2 escherichia coli mycobacterium tuberculosis 1undefined  1 

문제는 cat

+0

내가 도움을 싶지만, 나는 네트워크/그래프 이론에 익숙하지 않다. 이 행 중 하나를 계산할 수있는 방법의 예를 보여줄 수 있습니까? – Clarinetist

+0

어떤 행입니까? 원본 대상 테이블[email protected] – CodeNoob

+0

그래, 그거야. – Clarinetist

답변

1

아마도이 작업을 수행하는 더 좋은 방법입니다. 업데이트 된 데이터 세트와

library(dplyr) 
library(gtools) 
library(tidyr) 

test.set <- read.table(text = " 
          cluster.id letters cat 
         1   5  A  pink 
         2   4  B  blue 
         3   4  B  blue 
         4   3  A  pink 
         5   3  E  pink 
         6   3  D  pink 
         7   3  C  pink 
         8   2  A  blue 
         9   2  E  blue 
         10   1  A  green 
         11   0  A  pink 
         12   0  E  pink", header = T, stringsAsFactors = F) 

x <- test.set %>% 
    group_by(cluster.id) %>% 
    mutate(letter.count = n_distinct(letters)) %>% 
    filter(letter.count > 1) %>% 
    select(-letter.count) %>% 
    ungroup() %>% 
    mutate(id = paste(cluster.id, cat), 
     ind = 1) %>% 
    select(-cluster.id, -cat) %>% 
    spread(key = letters, value = ind) %>% 
    as.data.frame() 

row.names(x) <- x$id 
x$id <- NULL 

for (i in 1:nrow(x)){ 
    cluster <- x[i,] 
    letters <- names(cluster)[which(!is.na(cluster))] 
    comb <- combinations(n = length(letters), 
         r = 2, 
         v = letters) %>% 
    as.data.frame() %>% 
    rename(source = V1, 
      target = V2) 
    cat <- sub(". ", "", dimnames(cluster)[[1]]) 
    comb$cat <- cat 
    rm(cat) 
    comb$weight <- 0 
    cluster_cols <- dimnames(cluster)[[2]] 
    for (j in 1:nrow(comb)){ 
    comb$weight[j] <- min(cluster[cluster_cols == comb$source[j]], 
          cluster[cluster_cols == comb$target[j]]) + comb$weight[j] 
    } 
    rm(j) 
    rm(cluster_cols) 
    if (i == 1){ 
    final <- comb 
    rm(comb) 
    } else { 
    final <- rbind(final, comb) 
    rm(comb) 
    } 
} 

rm(i) 

final <- final %>% 
    group_by(source, target, cat) %>% 
    summarize(weight = sum(weight)) %>% 
    ungroup() 

> final 
# A tibble: 7 x 4 
    source target cat weight 
    <fctr> <fctr> <chr> <dbl> 
1  A  E blue  1 
2  A  E pink  2 
3  A  C pink  1 
4  A  D pink  1 
5  C  E pink  1 
6  C  D pink  1 
7  D  E pink  1 

(cat <- sub(".* ", "", dimnames(cluster)[[1]])로 변경 cat <- sub(". ", "", dimnames(cluster)[[1]])) : 여기

내 시도이다

txt <- "cluster.id\tletters\tcat 
10283\tklebsiella pneumoniae\tprotein1 
10463\tescherichia coli\tundefined 
10463\tmycobacterium tuberculosis\tundefined 
10\tescherichia coli\tundefined 
10\tmycobacterium tuberculosis\tundefined" 

library(dplyr) 
library(gtools) 
library(tidyr) 
library(stringr) 

test.set <- read.table(text = txt, header = TRUE, sep = "\t", stringsAsFactors = FALSE) %>% 
    as.data.frame() 
rm(txt) 

x <- test.set %>% 
    group_by(cluster.id) %>% 
    mutate(letter.count = n_distinct(letters)) %>% 
    filter(letter.count > 1) %>% 
    select(-letter.count) %>% 
    ungroup() %>% 
    mutate(id = paste(cluster.id, cat), 
     ind = 1) %>% 
    select(-cluster.id, -cat) %>% 
    spread(key = letters, value = ind) %>% 
    as.data.frame() 

row.names(x) <- x$id 
x$id <- NULL 

for (i in 1:nrow(x)){ 
    cluster <- x[i,] 
    letters <- names(cluster)[which(!is.na(cluster))] 
    comb <- combinations(n = length(letters), 
         r = 2, 
         v = letters) %>% 
    as.data.frame() %>% 
    rename(source = V1, 
      target = V2) 
    cat <- sub(".* ", "", dimnames(cluster)[[1]]) 
    comb$cat <- cat 
    rm(cat) 
    comb$weight <- 0 
    cluster_cols <- dimnames(cluster)[[2]] 
    for (j in 1:nrow(comb)){ 
    comb$weight[j] <- min(cluster[cluster_cols == comb$source[j]], 
          cluster[cluster_cols == comb$target[j]]) + comb$weight[j] 
    } 
    rm(j) 
    rm(cluster_cols) 
    if (i == 1){ 
    final <- comb 
    rm(comb) 
    } else { 
    final <- rbind(final, comb) 
    rm(comb) 
    } 
} 

rm(i) 

final <- final %>% 
    group_by(source, target, cat) %>% 
    summarize(weight = sum(weight)) %>% 
    ungroup() 

출력 :

# A tibble: 1 x 4 
      source      target  cat weight 
      <fctr>      <fctr>  <chr> <dbl> 
1 escherichia coli mycobacterium tuberculosis undefined  2 
+0

늦게 응답 해 주셔서 (조만간 답장을하지 못했습니다). 이것은 내가 제공 한 테스트 세트에 대해 원하는 것을 수행하지만 실제 데이터 세트에 이상한 결과를 생성합니다 (cat 변수에 무언가를 붙여 넣기 때문에 결과가 정확하지 않습니다). 원래 데이터 세트의 일부로 내 질문을 업데이트했습니다. 어떻게 해결할 수 있을지 생각해보십시오. – CodeNoob

+0

@CodeNoob 편집을 참조하십시오. – Clarinetist

+0

@CodeNoob 만약 당신이 새로운 데이터 세트를 게시한다면,'R'에서 관련 발췌 부분을 걸러 내고 필터링 된 데이터 프레임에서'dput()'을 사용하십시오. 내가 제공 한 데이터 문자열을 다시 포맷해야한다는 것을 알게 될 것입니다. – Clarinetist