Próbuję obliczyć odległości euklidesowe między jednym z jednej strony a wieloma wektory z drugiej strony za pomocą R.

Jak dotąd śledzę tę dokumentację HTTPS: // Cran. r-project.org/web/packages/neighbr/neighbr.pdf i używana odległość (X, Y, "Euclidean"). Działa to doskonale, jeśli obliczę tylko odległość między dwoma wektorami, tj. Kiedy mam jeden wiersz danych w obu X i Y. Jednak w moim oryginalnym zestawie danych mam wiele wierszy w Y i chciałbym obliczyć odległości między każdym z tych rzędów a pojedynczym rzędem w x.

Jak to możliwe?

x = structure(list(`Feature I` = 0.85649790378586, `Feature II` = 0.851856356221207, `Feature III` = 0.799580263077569, `Feature IV` = 0.895081402129565, `Feature V` = 0.920173237422567), row.names = c(NA, -1L), class = c("tbl_df", "tbl", "data.frame"))
y = structure(list(`Feature I` = c(0.0444280626160322, 0.00326398594129033, 0.0218000692329814), `Feature II` = c(0.0481646509894741, 0.00509786237104908, 0.0276902769176258), `Feature III` = c(0.0456380620204004, 0.00422956673025977, 0.0347273727088683), `Feature IV` = c(0.0365954415011219, 0.00422974884164406, 0.0328151120410415), `Feature V` = c(0.0384331094111439, 0.00362614754925969, 0.0260414956219995)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
0
MSC 28 październik 2020, 18:28

1 odpowiedź

Najlepsza odpowiedź

Dostosowanie Ta odpowiedź do danych:

y$dist_from_x = t(outer(
  1:nrow(x),
  1:nrow(y),
  FUN = Vectorize(function(xi,yi) dist(rbind(x[xi,],y[yi,])))
))

y
#     Feature I  Feature II Feature III  Feature IV   Feature V dist_from_x
# 1 0.044428063 0.048164651 0.045638062 0.036595442 0.038433109    1.840726
# 2 0.003263986 0.005097862 0.004229567 0.004229749 0.003626148    1.926465
# 3 0.021800069 0.027690277 0.034727373 0.032815112 0.026041496    1.871883

Ponieważ x ma jeden wiersz, byłoby to trochę bardziej wydajne:

# reset definition of y (or remove the dist_from_x column)
x_expanded = x[rep(1, nrow(y)), ]
y$dist_from_x = sqrt(rowSums((x_expanded - y)^2))
# same result as above
0
Gregor Thomas 28 październik 2020, 17:00