Я пытаюсь рассчитать расстояние между определенными точками, содержащимися в массиве в R. Мои данные выглядят так:
curve_array
, , Frame001.txt
[,1] [,2]
[1,] 30.13947 -16.92239
[2,] 30.34071 -16.72115
[3,] 30.53260 -16.52926
[4,] 30.72348 -16.33496
[5,] 30.92572 -16.13614
[6,] 31.13358 -15.95087
[7,] 31.34144 -15.76561
[8,] 31.52396 -15.58309
[9,] 31.73182 -15.39782
[10,] 31.95565 -15.21917
[11,] 32.17287 -15.02455
, , Frame002.txt
[,1] [,2]
[1,] 30.13947 -16.92239
[2,] 30.34071 -16.72115
[3,] 30.53260 -16.52926
[4,] 30.72348 -16.33496
[5,] 30.92572 -16.13614
[6,] 31.13358 -15.95087
[7,] 31.34144 -15.76561
[8,] 31.52396 -15.58309
[9,] 31.73182 -15.39782
[10,] 31.95565 -15.21917
[11,] 32.17287 -15.02455
, , Frame003.txt
[,1] [,2]
[1,] 30.13947 -16.92239
[2,] 30.34071 -16.72115
[3,] 30.53260 -16.52926
[4,] 30.72348 -16.33496
[5,] 30.92572 -16.13614
[6,] 31.13358 -15.95087
[7,] 31.34144 -15.76561
[8,] 31.52396 -15.58309
[9,] 31.73182 -15.39782
[10,] 31.95565 -15.21917
[11,] 32.17287 -15.02455
И для каждого среза я пытаюсь вычислить расстояние между точками, содержащимися в строке [1,] и строке [11,] (первая и последняя точки).
Я действительно ничего не добился с этим (я пробовал функцию dist и функцию geomorph::interlmkdist), поэтому любая помощь будет очень признательна. Совсем недавно я попробовал функцию usedist::dist_subset, но она показала следующую ошибку: «Ошибка в as.matrix(d)[idx, idx]: нет атрибута dimnames для массива».
Мне удалось использовать функцию DistancePointToPoint, но мне приходится вручную вводить значения из строк [1,] и [11,], которые, учитывая размер массива, не идеальны.
В идеале я хочу вернуть массив, который выглядит примерно так:
,, Frame001.txt
[1] 2.781459
,, Frame002.txt
[1] 2.781459
,, Frame003.txt
[1] 2.781459
etc.
Спасибо!
dput(curve_array)
structure(c(30.1394716184822, 30.3407126170086, 30.5325951613319,
30.7234753517486, 30.9257187041817, 31.1335771291367, 31.3414355540918,
31.5239596442118, 31.7318180691669, 31.9556523747537, 32.172869253912,
-16.9223869881883, -16.7211459896618, ...), dim = c(11L,
2L, 47L), dimnames = list(NULL, NULL, c("Frame001.txt", "Frame002.txt",
"Frame003.txt", "Frame004.txt", "Frame005.txt", "Frame006.txt",
"Frame007.txt", "Frame008.txt", "Frame009.txt", "Frame010.txt",
"Frame011.txt", "Frame012.txt", "Frame013.txt", "Frame014.txt",
"Frame015.txt", "Frame016.txt", "Frame017.txt", "Frame018.txt",
"Frame019.txt", "Frame020.txt", "Frame021.txt", "Frame022.txt",
"Frame023.txt", "Frame024.txt", "Frame025.txt", "Frame026.txt",
"Frame027.txt", "Frame028.txt", "Frame029.txt", "Frame030.txt",
"Frame031.txt", "Frame032.txt", "Frame033.txt", "Frame034.txt",
"Frame035.txt", "Frame036.txt", "Frame037.txt", "Frame038.txt",
"Frame039.txt", "Frame040.txt", "Frame041.txt", "Frame042.txt",
"Frame043.txt", "Frame044.txt", "Frame045.txt", "Frame046.txt",
"Frame047.txt")))
@RicVillalba Я включил его в пост, так как он слишком длинный для комментариев.





Вы можете использовать apply вдоль третьего поля, чтобы применить операцию расстояния к каждому фрагменту вашего массива. Это просто функция евклидова расстояния между первой и 11-й строками. Результатом является именованный вектор:
apply(curve_array, 3, function(x) sqrt((x[1, 1]-x[11, 1])^2 + (x[1, 2]-x[11, 2])^2))
#> Frame001.txt Frame002.txt Frame003.txt Frame004.txt Frame005.txt
#> 2.781455 2.781455 2.781455 2.781455 2.668020
#> Frame006.txt Frame007.txt Frame008.txt Frame009.txt Frame010.txt
#> 2.548641 2.350681 2.121847 1.791864 1.446678
#> Frame011.txt Frame012.txt Frame013.txt Frame014.txt Frame015.txt
#> 1.192961 1.054892 1.074074 1.182647 1.403697
#> Frame016.txt Frame017.txt Frame018.txt Frame019.txt Frame020.txt
#> 1.644818 1.889481 2.036533 2.155975 2.240272
#> Frame021.txt Frame022.txt Frame023.txt Frame024.txt Frame025.txt
#> 2.380460 2.484956 2.530551 2.537903 2.557738
#> Frame026.txt Frame027.txt Frame028.txt Frame029.txt Frame030.txt
#> 2.580983 2.659684 2.638101 2.697796 2.698458
#> Frame031.txt Frame032.txt Frame033.txt Frame034.txt Frame035.txt
#> 2.700066 2.693820 2.727060 2.718718 2.631126
#> Frame036.txt Frame037.txt Frame038.txt Frame039.txt Frame040.txt
#> 2.702522 2.744878 2.787322 2.758420 2.801023
#> Frame041.txt Frame042.txt Frame043.txt Frame044.txt Frame045.txt
#> 2.772264 2.772264 2.793633 2.750915 2.686989
#> Frame046.txt Frame047.txt
#> 2.715900 2.665723
Что вы подразумеваете под "расстоянием"? Учитывая ваши значения, я предполагаю, что это географические координаты, и что вам нужно географическое расстояние на сфероиде, а не евклидово расстояние.
Если это так, вы можете получить расстояние между первой и 11-й строками для одной матрицы, подобной этой.
library(geosphere)
distGeo(curve_array[1,,1], curve_array[11,,1])
[1] 302457.3
Предполагая, что данные находятся в порядке долготы (x)/широты (y), а не наоборот!
И для всего этого
a <- apply(curve_array, 3, \(m) distGeo(m[1,], m[11,]))
head(a)
#Frame001.txt Frame002.txt Frame003.txt Frame004.txt Frame005.txt Frame006.txt
# 302457.3 302457.3 302457.3 302457.3 290466.7 278119.9
Для евклидова расстояния вы можете использовать
b <- apply(curve_array, 3, \(m) dist(m[c(1,11), ]))
head(b)
#Frame001.txt Frame002.txt Frame003.txt Frame004.txt Frame005.txt Frame006.txt
# 2.781455 2.781455 2.781455 2.781455 2.668020 2.548641
Это тот же результат, что и в ответе Аллана Кэмерона.
И просто упомянем, что \(m) эквивалентно function(m)
Спасибо! Это полезно. В этом случае мне нужно было евклидово расстояние, но все же приятно видеть, как можно рассчитать географическое расстояние :)
С некоторыми подмножествами apply() хорошо работает и с dist():
apply(curve_array[c(1,11),,], 3, dist)
#> Frame001.txt Frame002.txt Frame003.txt Frame004.txt Frame005.txt Frame006.txt
#> 2.781455 2.781455 2.781455 2.781455 2.668020 2.548641
#> Frame007.txt Frame008.txt Frame009.txt Frame010.txt Frame011.txt Frame012.txt
#> 2.350681 2.121847 1.791864 1.446678 1.192961 1.054892
#> Frame013.txt Frame014.txt Frame015.txt Frame016.txt Frame017.txt Frame018.txt
#> 1.074074 1.182647 1.403697 1.644818 1.889481 2.036533
#> Frame019.txt Frame020.txt Frame021.txt Frame022.txt Frame023.txt Frame024.txt
#> 2.155975 2.240272 2.380460 2.484956 2.530551 2.537903
#> Frame025.txt Frame026.txt Frame027.txt Frame028.txt Frame029.txt Frame030.txt
#> 2.557738 2.580983 2.659684 2.638101 2.697796 2.698458
#> Frame031.txt Frame032.txt Frame033.txt Frame034.txt Frame035.txt Frame036.txt
#> 2.700066 2.693820 2.727060 2.718718 2.631126 2.702522
#> Frame037.txt Frame038.txt Frame039.txt Frame040.txt Frame041.txt Frame042.txt
#> 2.744878 2.787322 2.758420 2.801023 2.772264 2.772264
#> Frame043.txt Frame044.txt Frame045.txt Frame046.txt Frame047.txt
#> 2.793633 2.750915 2.686989 2.715900 2.665723
пожалуйста
dput(curve_array)и скопируйте/вставьте вывод