2017-11-22 6 views
0

질문
R : 페어의 조합을 사용하여 업데이트 인접 행렬/데이터 프레임


의 내가이 dataframe 있다고 가정 해 봅시다 :

# mock data set 
df.size = 10 
cluster.id<- sample(c(1:5), df.size, replace = TRUE) 
letters <- sample(LETTERS[1:5], df.size, replace = TRUE) 
test.set <- data.frame(cluster.id, letters) 

이됩니다 뭔가 같은 :

 cluster.id letters 
     <int> <fctr> 
1   5  A 
2   4  B 
3   4  B 
4   3  A 
5   3  E 
6   3  D 
7   3  C 
8   2  A 
9   2  E 
10   1  A 

이제 cluster.id 및 클러스터 내에서 어떤 글자를 볼 수 있는지 알아보십시오. 예를 들어 cluster 3에는 A,E,D,C이라는 글자가 있습니다. 그럼 난 (자체 그래서 아무 A,A 예를 들어, 함께하지만 조합) ​​모든 고유 페어 조합을 얻으려면 : A,E ; A,D, A,C etc. 그런 다음 내가 인접 행렬/데이터 프레임에서 이러한 조합에 대한 페어의 거리를 업데이트 할. 내가


# empty adjacency df 
possible <- LETTERS 
adj.df <- data.frame(matrix(0, ncol = length(possible), nrow = length(possible))) 
colnames(adj.df) <- rownames(adj.df) <- possible 


# what I tried 
update.adj <- function(data) { 
    for (comb in combn(data$letters,2)) { 
    # stucked 
    } 
} 

test.set %>% group_by(cluster.id) %>% update.adj(.) 

을 시도 무엇

아이디어


# group by cluster.id 
# per group get all (unique) pairwise combinations for the letters (excluding pairwise combinations with itself, e.g. A,A) 
# update adjacency for each pairwise combinations 

아마, 내가 인접 행렬을 항상 볼 수 있기 때문에이 작업을 수행 할 수있는 쉬운 방법이있다 그러나 나는 그것을 알아낼 수 없다. 을 나는 (아래의 표는 "같은 것") 예를 들어 준 데이터의 경우 : 자체는


대답 @Manuel BICKEL에
대답을 언급하는 것이 분명하지 않다 있으면 알려 주시기 이를 행렬은 전체 데이터 집합에 대해 A -> Z가 될 것이므로이를 명심하십시오.

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

내가 무슨 짓을했는지 설명합니다 : 더> 1 고유의 편지를 포함

cluster.id letters 
     <int> <fctr> 
1   5  A 
2   4  B 
3   4  B 
4   3  A 
5   3  E 
6   3  D 
7   3  C 
8   2  A 
9   2  E 
10   1  A 

만 클러스터 관련이 (우리가 자체 전자 조합을 원하지 않기 때문에.g 클러스터 1)에만 문자 B를 포함하는, 그래서 조합 B,B 발생하기 때문에 관련이없는 것 :

이제
4   3  A 
5   3  E 
6   3  D 
7   3  C 
8   2  A 
9   2  E 

내가 할 수 페어 어떤 조합 각 클러스터를 찾습니다 :

클러스터 3 :

A,E 
A,D 
A,C 
E,D 
E,C 
D,C 

업데이트 인접 행렬에서 이러한 조합 :

는 그런 다음 클러스터로 이동

클러스터 2

A, E

업데이트 다시 인접 행렬 : 반응 t으로

A B C D E 
A 0 0 1 1 2 <-- note the 2 now 
B 0 0 0 0 0 
C 1 0 0 1 1 
D 1 0 1 0 1 
E 2 0 1 1 0 

주석 위에 다음 거대한 데이터 세트

library(reshape2) 

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

x1 <- reshape2::dcast(test.set, cluster.id ~ letters) 

x1 
#cluster.id A B C D E 
#1   1 1 0 0 0 0 
#2   2 1 0 0 0 1 
#3   3 1 0 1 1 1 
#4   4 0 2 0 0 0 
#5   5 1 0 0 0 0 

x2 <- table(test.set) 

x2 
#   letters 
#cluster.id A B C D E 
#   1 1 0 0 0 0 
#   2 1 0 0 0 1 
#   3 1 0 1 1 1 
#   4 0 2 0 0 0 
#   5 1 0 0 0 0 


x1.c <- crossprod(x1) 
#Error in crossprod(x, y) : 
# requires numeric/complex matrix/vector arguments 

x2.c <- crossprod(x2) 
#works fine 
+0

예상되는 출력이 어떻게 표시되는지 완전히 이해하지 못합니다. 예를 들어 주시겠습니까? 감사합니다. –

+0

각 클러스터에서 조합이 발견되는 빈도를 나타내는 count가 채워진 adj.df입니다. 이것이 의미가 있습니까? @ManuelBickel – CodeNoob

+0

개별 클러스터 내에서 조합에 관한 부분을 얻었지만'update.adj'의 출력 내용을 완전히 이해하지 못했습니다. 간단한 예제 출력을 제공 할 수 있습니까? (매우 짧을 수 있습니다, 예 : 2x2 정도) –

답변

2

O를, 타일러 스케이트 타는 사람의 여기 코드는 데이터를 사용했다. 나는 이것이 당신이 원하는 바란다.

업데이트 : 아래의 의견에 따라 더 많은 양의 데이터를 처리 할 수 ​​있도록 reshape2 패키지를 사용하여 솔루션을 추가했습니다.

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

x <- table(test.set) 
x 
      letters 
#cluster.id A B C D E 
#   1 1 0 0 0 0 
#   2 1 0 0 0 1 
#   3 1 0 1 1 1 
#   4 0 2 0 0 0 
#   5 1 0 0 0 0 

#base approach, based on answer by Tyler Rinker 
x <- crossprod(x) 
diag(x) <- 0 #this is to set matches such as AA, BB, etc. to zero 
x 

#   letters 
# letters 
#   A B C D E 
#  A 0 0 1 1 2 
#  B 0 0 0 0 0 
#  C 1 0 0 1 1 
#  D 1 0 1 0 1 
#  E 2 0 1 1 0 

#reshape2 approach 
x <- acast(test.set, cluster.id ~ letters) 
x <- crossprod(x) 
diag(x) <- 0 
x 
# A B C D E 
# A 0 0 1 1 2 
# B 0 0 0 0 0 
# C 1 0 0 1 1 
# D 1 0 1 0 1 
# E 2 0 1 1 0 
+0

감사합니다. 어떻게합니까? 편지가 같은 클러스터에 있는지 확인하십시오. – CodeNoob

+0

제 대답에'table()'호출의 출력을 추가했습니다. 이렇게하면 클러스터 당 각 글자 수가 계산됩니다. 교차 제품은 마침내 가능한 조합의 모든 수를 말하며, 이는 찾고있는 인접성 수입니다 (매트릭스 m의 교차 제품을 쓰는 또 다른 방법은'% * % t (m)'). 그게 도움이 되니? –

+0

매우 쉬운 hahah를 보아라, 이것과 관련된 문제는 "테이블 (탭)의 에러 :> = 2^31 개 요소를 가진 테이블을 만들려고 시도한다"이다. 원래 데이터 세트가 크기 때문에 @Manuel Bickel – CodeNoob

관련 문제