2015-08-18 13 views
6

mam matrycę dystans:Skutecznie korzystające parami odległości

> mat 
      hydrogen helium lithium beryllium boron 
hydrogen 0.000000 2.065564 3.940308 2.647510 2.671674 
helium 2.065564 0.000000 2.365661 1.697749 1.319400 
lithium 3.940308 2.365661 0.000000 3.188148 2.411567 
beryllium 2.647510 1.697749 3.188148 0.000000 2.499369 
boron  2.671674 1.319400 2.411567 2.499369 0.000000 

oraz ramkę danych:

> results 

El1  El2 Score 
Helium Hydrogen 92 
Boron Helium 61 
Boron Lithium 88 

Chcę obliczyć wszystkie parami odległości między słowami w results$El1 i results$El2 aby uzyskać następnie:

> results 

El1  El2 Score Dist 
Helium Hydrogen 92 2.065564 
Boron Helium 61 1.319400 
Boron Lithium 88 2.411567 

Zrobiłem to z pętlą for, ale wydaje się naprawdę niezgrabny. Czy istnieje bardziej elegancki sposób wyszukiwania i wyodrębniania odległości z mniejszą liczbą linii kodu?

Tu jest mój bieżący kod:

names = row.names(mat) 
num.results <- dim(results)[1] 
El1 = match(results$El1, names) 
El2 = match(results$El2, names)  
el.dist <- matrix(0, num.results, 1)   
for (i1 in c(1:num.results)) {    
el.dist[i1, 1] <- mat[El1[i1], El2[i1]] 
} 
results$Dist = el.dist[,1] 

Odpowiedz

4
cols <- match(tolower(results$El1), colnames(mat)) 
rows <- match(tolower(results$El2), colnames(mat)) 
results$Dist <- mat[cbind(rows, cols)] 
results 
    El1  El2 Score  Dist 
1 Helium Hydrogen 92 2.065564 
2 Boron Helium 61 1.319400 
3 Boron Lithium 88 2.411567 

Rozpoznasz większość kodu. Ten, na którym należy się skupić, to mat[cbind(rows, cols)]. W przypadku macierzy możemy dokonać podzbioru według innej macierzy z taką samą liczbą kolumn, co wymiary. Od ?`[` pomoc:

Podczas indeksowania tablic przez [jeden argument i może być macierz z tyle kolumn, ile jest wymiarów x; wynikiem jest wektor z elementami odpowiadającymi zestawom wskaźników w każdym wierszu i.

+0

Usunąłem poprzedni komentarz po znalezieniu problem: nieuczciwe litery! – Dex

3

Innym podejściem

results$Dist <- mapply(function(x, y) mat[tolower(x), tolower(y)], 
         results$El1, results$El2) 

Zakłada results korzystanie character nie factor dla El1 i El2.

Wynik

> results 
    El1  El2 Score  Dist 
1 Helium Hydrogen 92 2.065564 
2 Boron Helium 61 1.319400 
3 Boron Lithium 88 2.411567 
+0

Dziękujemy! Po prostu próbowałem tego i działało dobrze, chociaż "El1" i "El2" są czynnikami. Czy nie zaleca się używania 'mapply' z czynnikami? – Dex

+1

@ user20672 - różnica czynnik/znak zmieni wyniki, które zostaną zwrócone, gdy możliwe jest indeksowanie liczbą całkowitą ** lub ** znakiem. Współczynnik jest wewnętrznie całkowitą ... więc 'x <- c (b = 1, a = 2)', a następnie 'x [współczynnik (c (" a "," b "))]' i 'x [c ("a", "b")] 'zwróci różne odpowiedzi. – thelatemail

+0

@ Dziękujemy za wyjaśnienie – Dex

Powiązane problemy