停留在一个看似简单的问题的可伸缩性上。目的是获得每个点到子点簇的中心的矢量“距离”。
首先让我们生成一些虚拟数据:
library(data.table)
training <- data.table(X1 = rnorm(100), # 3D measures divided in 2 groups 1 and 0
X2 = rnorm(100, 5),
X2 = rnorm(100, 10),
Thr = sample(c(1,0), 100, replace = TRUE))
现在,我想找到阈值以上的子组的中心。重要的是,群集必须仅包含组1的点进行分层处理。
Centre_coords <- paste0("Centre_", 1:3) # Vector of new variables
training[Thr == 1, # Here I filter for the points above the threshold
c(Centre_coords ) := apply(.SD, # Here I would like to apply some clustering such as means or pam, but I was not able
FUN = mean), # implement it efficiently, thus, I used the mean as for the centre of each coordinate
.SDcols = c("X1","X2", "X3")]
在这里,我认为我开始犯“错误”。我的意思是说我使用的方法可以完成任务,但是它们既不干净也不高效,因为我必须将所有中心存储在单独的列向量中。然后,我需要执行另一个丑陋的步骤,以使“中心”值可访问组Thr == 1之外的值,因为我想获取每个点(组1和0)到群集组1中心的距离技巧如下:
training[, c(Centre_coords) :=lapply(.SD,
FUN = na.locf, # Fill NA so that we can use the centers as reference
fromLast = TRUE),
.SDcols = c(Centre_coords)][, c(Centre_coords) :=lapply(.SD,
FUN = function(x) {ifelse(is.na(x), max(x, na.rm = T),x)} # Fill NA so that we can use the centers as reference
),
.SDcols = c(Centre_coords)
]
最后,使用中心向量和每个坐标中点的向量,我使用一个自定义函数来计算两者之间的欧几里得距离,并在称为“距离”的向量中捕获该距离。
euc.dist <- function(x1, x2) sqrt(sum((x1 - x2) ^ 2)) # function to calculate distances
training[, Distance := sum( euc.dist(X1, Centre_1) +
euc.dist(X2, Centre_2) +
euc.dist(X3, Centre_3))
]
这段代码完全可以完成我的工作,但是它们很慢并且看起来过于复杂,因此我正在寻找可以改进的地方。另外,我使用data.table框架的原因是因为速度,因为我必须将此距离计算应用于大约200万行的数据集,但是,我对其他框架(例如带有良好管道的tidyverse)持开放态度。我特别希望摆脱Centers的影响,并即时进行所有操作。
期待您的评论。
对于我在手机上写的任何错字或错误,我深表歉意。