我的任务是基于自定义的距离度量创建距离矩阵函数。 距离量度如下:
wabs_dist = function(u, v, w){
return( sum((abs(u-v))*w) )
}
其中u和v是向量,w是权重。
我要解决的问题:
我要创建一个距离矩阵函数create-dm(x,w),通过为所有对象对a和a调用wabs-dist(a,b,w)来返回数据帧x中对象的距离矩阵。 b属于x。如果x是具有4个属性的数据集,则w是向量,例如w = c(1,1,3,2)分配给每个属性。是的,已经有像dist()这样的标准函数,但是我要在这里使用wabs_dist创建自己的函数。
到目前为止,我的解决方案是
create_dm = function(x, w){ #x is a dataframe
distances = matrix(0, nrow = nrow(x), ncol = nrow(x))
for (i in 1:nrow(x)) {
for(j in 1:(i-1)){
distances[i, j] = wabs_dist(x[i,], x[j,], w)
distances[j, i] = distances[i, j]
}
}
return(distances)
}
我如何实现权重向量,因为我本着编写仅传递一个权重的思想来编写此函数的方法,但是现在我必须编写它才能接受列表。如何使用权重列表实现此功能?
此功能需要大量时间才能运行。实际上,它从未真正打印出距离矩阵函数。我不知道为什么
一个例子:
让x为包含向量a,b和c的数据帧,其中: 答:(1、2) b:(4、5) c:(9,12)
w是权重向量:(0.2,0.3)
wabs-dist(a,b,w)= 1.5 wabs-dist(b,c,w)= 3.1
create-dm(x,w)=
0 1.5 4.6
1.5 0 3.1
4.6 3.1 0
答案 0 :(得分:1)
我最近有一个类似的问题。我的最终解决方案是使用Rcpp软件包用C ++编写它。将此代码另存为dmat.cpp
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix dmat(NumericMatrix x, NumericVector w) {
int n = x.nrow();
NumericMatrix d = no_init_matrix(n, n);
for(int i=0; i<n;i++){
for(int j=i+1; j<n;j++){
d(i,j)=sum(w*abs((x(i,_)-x(j,_))));
d(j,i)=d(i,j);
}
d(i,i)=0;
}
return d;
}
然后安装并加载软件包“ Rcpp”,并使用sourceCpp()
加载该功能。之后,您可以像使用其他任何R函数一样使用它
library(Rcpp)
sourceCpp("path/to/file/dmat.cpp")
x <- matrix(rnorm(1500),ncol=3)
w <- 1:3
system.time(distR <- create_dm(x,w))
User System verstrichen
1.81 0.02 1.84
system.time(distCpp <- dmat(x,w))
User System verstrichen
0 0 0
identical(round(distR,10), round(distCpp,10))
[1] TRUE
如果仅使用identical()
而不四舍五入,则结果为FALSE。不知道为什么。也许可以由其他人回答。
如果可以使用欧几里德距离而不是绝对距离,则可以使用软件包apcluster
。这是我的第一个解决方案。但是C ++解决方案仍然更快。