Преобразование вывода combn в матрицу типа dist

У меня есть датафрейм в следующем виде:

   dim1  dim2
1 Loc.1 0.325
2 Loc.2 0.325
3 Loc.3 0.321
4 Loc.4 0.256
5 Loc.5 0.255

Я хотел бы вычислить среднее значение каждой комбинации двух (2) элементов в «dim2»; и преобразовать вывод в матрицу; при сохранении информации, предоставленной dim1.

А пока я могу получить попарные средства с помощью функции combn:

combn(tab[,2],2, mean)
[1] 0.3250 0.3230 0.2905 0.2900 0.3230 0.2905 0.2900 0.2885 0.2880 0.2555

но я бы хотел, чтобы он отображался в матричной форме (которая на самом деле была бы очень похожа на объект класса dist, как я бы хотел, чтобы он был для дальнейшего анализа) следующим образом:

        Loc.1   Loc.2   Loc.3   Loc.4
Loc.2   0.325           
Loc.3   0.323   0.323       
Loc.4   0.290   0.291   0.289   
Loc.5   0.290   0.290   0.288   0.256

(и мне также нужна, как видите, информация Loc.x)

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

Любое предложение? Большое спасибо!


person Chrys    schedule 16.04.2018    source источник


Ответы (3)


Вот однострочный текст с использованием expand.grid вместо combn.

as.dist(matrix(apply(expand.grid(tab[, 2], tab[, 2]), 1, mean), 5, 5))
#       1      2      3      4
#2 0.3250
#3 0.3230 0.3230
#4 0.2905 0.2905 0.2885
#5 0.2900 0.2900 0.2880 0.2555

Причина, по которой это работает, заключается в том, что expand.grid рассматривает все возможные комбинации двух векторов-столбцов tab[, 2], а combn пропускает диагональные элементы; Затем мы последовательно обрабатываем матрицу комбинирования, вычисляем средние и преобразуем vector сначала как matrix, а затем как объект dist.

person Maurits Evers    schedule 16.04.2018

Вот относительно простой способ преобразовать вектор в матрицу расстояний:

vec <- c(0.3250, 0.3230, 0.2905, 0.2900, 0.3230, 0.2905, 0.2900, 0.2885, 0.2880, 0.2555)

mat <- matrix(nrow = 5, ncol = 5)
mat[lower.tri(mat)] <- vec
mat <- as.dist(mat)

#output
> mat
       1      2      3      4
2 0.3250                     
3 0.3230 0.3230              
4 0.2905 0.2905 0.2885       
5 0.2900 0.2900 0.2880 0.2555
person missuse    schedule 16.04.2018

Вы также можете использовать функцию outer.

dim2 <- as.numeric(tab$dim2)
names(dim2) <- tab$dim1
x <- outer(dim2, dim2, function(x,y) (x + y) / 2)
as.dist(x)
#        Loc.1  Loc.2  Loc.3  Loc.4
# Loc.2 0.3250                     
# Loc.3 0.3230 0.3230              
# Loc.4 0.2905 0.2905 0.2885       
# Loc.5 0.2900 0.2900 0.2880 0.2555
person hpesoj626    schedule 16.04.2018
comment
Всем огромное спасибо! Все эти ответы очень полезны. Всего наилучшего! - person Chrys; 16.04.2018