与任意数量列的欧氏距离

问题描述 投票:0回答:2

我正在尝试根据任意列列表计算欧几里德距离。我尝试这样做来计算

dt
中的观测值与
x
中的单个观测值之间的距离。这似乎按预期计算,但我在第 4 行收到警告,因为我没有按引用分配。

dt <- data.table(a=1:10, b=11:20, c=21:30)
x <- data.table(a=5, b=6, c=7)
for(i in names(dt)){
  dt[[i]] <- (dt[[i]] - x[1][[i]])^2
}
dt[, euclid := rowSums(.SD), .SDcols=names(dt)]
dt[, euclid := sqrt(euclid)]

然后我将第 4 行替换为

setattr(dt, i, (dt[[i]] - x[1][[i]])^2)
但实际上它并没有更新列。

我可能误解了

setattr()
的工作原理。我认为以下两行是等效的,但显然不是。

dt[, foo := 2]
setattr(dt, "foo", 2)

我欢迎任何关于如何更好地做到这一点的想法和建议。

我有data.table v1.15.4

r data.table
2个回答
0
投票

这是一种不更改原始列值的方法

cbind(dt, 
  dt[, lapply(names(.SD), \(i) (.SD[,get(i)] - x[,get(i)])^2)][
    , .(euclid = sqrt(rowSums(.SD)))])
        a     b     c   euclid
    <int> <int> <int>    <num>
 1:     1    11    21 15.39480
 2:     2    12    22 16.43168
 3:     3    13    23 17.57840
 4:     4    14    24 18.81489
 5:     5    15    25 20.12461
 6:     6    16    26 21.49419
 7:     7    17    27 22.91288
 8:     8    18    28 24.37212
 9:     9    19    29 25.86503
10:    10    20    30 27.38613

0
投票

有这样的事吗?

dt[, euclid := sqrt(rowSums(mapply(function(a, b) (a-b)^2, .SD, x)))]
#         a     b     c   euclid
#     <int> <int> <int>    <num>
#  1:     1    11    21 15.39480
#  2:     2    12    22 16.43168
#  3:     3    13    23 17.57840
#  4:     4    14    24 18.81489
#  5:     5    15    25 20.12461
#  6:     6    16    26 21.49419
#  7:     7    17    27 22.91288
#  8:     8    18    28 24.37212
#  9:     9    19    29 25.86503
# 10:    10    20    30 27.38613
© www.soinside.com 2019 - 2024. All rights reserved.