我有随机群集的以下数据:
iris$cluster = sample(0:1, nrow(iris), replace=TRUE)
现在我使用以下代码计算两个集群的中心:
centers=iris %>%
group_by(cluster) %>%
summarise_at(vars(matches("Sepal")), mean)
现在我想为数据集中的每一行计算它们是否更接近中心的集群1的中心 因此,基本上中心0的欧氏距离与第1,2,3行等的1相比......
关于什么是最有效的做法的任何想法是R?
答案 0 :(得分:1)
根据问题的维度,一种方法是创建每行中心的排列,然后找到每行的最小值
library(data.table)
library(microbenchmark)
#create data
DT <- setDT(copy(iris))
set.seed(0L)
cols <- grep("^Sepal", names(DT), value=TRUE)
centers <- DT[, lapply(.SD, mean),
by=.("cluster"=sample(0:1, nrow(iris), replace=TRUE)),
.SDcols=cols]
setnames(centers, cols, paste0("mean_", cols))
CJ.dft <- function(...) {
Reduce(f=function(x, y) cbind(x[rep(1:nrow(x), times=nrow(y)),], y[rep(1:nrow(y), each=nrow(x)),]),
x=list(...)[-1],
init=..1)
} #CJ.dft
crossJoinMtd <- function() {
#cross join data with centers
ans <- CJ.dft(DT[, rn:=.I], centers)
#find the closest cluster
ans[,
.(ClosestCluster=cluster[which.min((Sepal.Length - mean_Sepal.Length)^2 + (Sepal.Width - mean_Sepal.Width)^2)]),
by=.(rn)]
}
样本用法:
crossJoinMtd()
# rn ClosestCluster
# 1: 1 1
# 2: 2 0
# 3: 3 0
# 4: 4 0
# 5: 5 1
# ---
#146: 146 1
#147: 147 0
#148: 148 1
#149: 149 1
#150: 150 0
一些时间:
microbenchmark(crossJoinMtd(),
times=100L)
# Unit: milliseconds
# expr min lq mean median uq max neval
# crossJoinMtd() 2.7325 3.03085 3.558447 3.26885 3.58805 14.6075 100
如果OP可以提供有关簇或维度数量的更多详细信息,则可以进一步优化。