Эффективный доступ к попарным расстояниям

у меня есть матрица расстояний:

> 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

и фрейм данных:

> results

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

Я хочу, чтобы вычислить все попарные расстояния между словами в results$El1 и results$El2 получить следующее:

> results

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

Я сделал это с циклом for, но он кажется действительно неуклюжим. Есть ли более элегантный способ поиска и извлечения расстояния с меньшим количеством строк кода?

вот мой текущий код:

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] 

2 ответов


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

вы узнаете большую часть кода. Один, чтобы сосредоточиться на mat[cbind(rows, cols)]. С матрицами нам разрешено подмножество другой матрицей с тем же количеством столбцов, что и размеры. От ?`[` справка:

при индексации массивов по [ одному аргументу i может быть матрицей с таким количеством столбцов, сколько есть измерений x; результатом является вектор с элементами, соответствующими наборам индексов в каждой строке i.


другой подход

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

предполагается results использовать character не factor на El1 и El2.

результат

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