Не следует удалять значения NA, они помогут при расчете расстояний.
Итак, начнем с ваших исходных данных:
df
V1 V2 V3 V4 V5
1 1 7 9 4 NA
2 3 6 NA NA NA
3 1 6 6 4 3
4 7 7 NA NA NA
5 4 3 1 8 NA
Мы пытаемся вычислить расстояния между всеми строки, использующие dist()
в одной go:
dst <- as.matrix(dist(df, diag=TRUE, upper=TRUE))
dst
1 2 3 4 5
1 0.000000 3.535534 3.535534 9.486833 11.456439
2 3.535534 0.000000 3.162278 6.519202 5.000000
3 3.535534 3.162278 0.000000 9.617692 8.587782
4 9.486833 6.519202 9.617692 0.000000 7.905694
5 11.456439 5.000000 8.587782 7.905694 0.000000
Теперь эти значения немного странные, не уверен, что это то, что вы ищете. Читая help(dist)
мы видим этот бит:
Если при вычислении евклидова, манхэттенского, канберрского или минковского расстояния некоторые столбцы исключаются, сумма масштабируется пропорционально количеству используемых столбцов. Если все пары исключаются при расчете определенного расстояния, значение равно «NA».
То, что это говорит - если ваши данные имеют NA, расстояния масштабируются, так что отсутствующие значения также добавляют на расстояние. Это делает расстояния сопоставимыми по размеру, несмотря на то, что некоторые элементы имеют значения NA.
Теперь, если вы этого не хотите, мы должны заново отрегулировать эти расстояния, чтобы они не масштабировались. Но сначала нам нужно понять, как они масштабируются.
Функция видит, что для некоторого определенного c расстояния использовались 2 из 5 столбцов, а остальные были NA. Он умножает сумму на расстоянии на 5/2, а затем принимает квадратное root значение (согласно евклидовой формуле) ios, 2-й - взять квадрат root значений этих крыс ios, а 3-й - перенастроить.
Начнем с того, что для каждого расстояния получаем количество элементов NA, использованных для их вычисления:
nas <- outer(rowSums(is.na(df)), rowSums(is.na(df)), FUN=pmax)
nas
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 1 3 1
[2,] 3 3 3 3 3
[3,] 1 3 0 3 1
[4,] 3 3 3 3 3
[5,] 1 3 1 3 1
Теперь, используя это, мы получаем часть данных, которые имели значения NA для каждого расстояния:
frac <- (ncol(df)-nas) / ncol(df)
frac
[,1] [,2] [,3] [,4] [,5]
[1,] 0.8 0.4 0.8 0.4 0.8
[2,] 0.4 0.4 0.4 0.4 0.4
[3,] 0.8 0.4 1.0 0.4 0.8
[4,] 0.4 0.4 0.4 0.4 0.4
[5,] 0.8 0.4 0.8 0.4 0.8
Мы видим, например, что для пары 1-2 у нас было 3 пропущенные значения и 2 доступных значения. Таким образом, доступные составляли 40% от целого.
Далее мы берем квадратные корни этих крыс ios и умножаем их на расстояния, которые мы получили (эти скорректированные расстояния), чтобы восстановить это масштабирование:
res <- dst * sqrt(frac)
res
1 2 3 4 5
1 0.000000 2.236068 3.162278 6.000000 10.246951
2 2.236068 0.000000 2.000000 4.123106 3.162278
3 3.162278 2.000000 0.000000 6.082763 7.681146
4 6.000000 4.123106 6.082763 0.000000 5.000000
5 10.246951 3.162278 7.681146 5.000000 0.000000
И это ваш результат. Итак, подведем итог:
dst <- as.matrix(dist(df, diag=TRUE, upper=TRUE))
nas <- outer(rowSums(is.na(df)), rowSums(is.na(df)), FUN=pmax)
frac <- (ncol(df)-nas) / ncol(df)
res <- dst * sqrt(frac)