示例代码如下所示,我想创建一个新对象d3=(d1+d2)/2
,但您知道d1
的项目与d2
的项目不同,所以直接使用添加是不可能的。有什么办法?
library(recommenderlab)
data(MSWeb)
d1 = dissimilarity(MSWeb[1:5,], method = "jaccard")
d2 = dissimilarity(MSWeb[2:6,], method = "jaccard")
答案 0 :(得分:1)
所以我假设你想在算术之前匹配距离矩阵之间的dimnames。据我所知,使用常规矩阵没有简单的方法,这意味着它对距离矩阵起作用的可能性更小。一种策略是用名称扩展距离矩阵值,进行合并和聚合,然后转换回距离矩阵。我已经创建了一些辅助函数来使这更容易。首先,这是一种将对角线距离矩阵转换为data.frame
中的成对距离的方法as.data.frame.dist<-function(x) {
stopifnot(is(x, "dist"))
s <- attr(x, "Size")
n <- attr(x, "Labels")
data.frame(
id1 = unlist(sapply(1:(length(n)-1), function(i) n[1:i])),
id2 = rep(n[-1], 1:(length(n)-1)),
dist = as.numeric(x)
)
}
例如,如果我们运行
as.data.frame(d1)
# id1 id2 dist
# 1 1 2 0.7500000
# 2 1 3 0.8000000
# 3 2 3 1.0000000
# 4 1 4 1.0000000
# 5 2 4 0.3333333
# 6 3 4 1.0000000
# 7 1 5 1.0000000
# 8 2 5 1.0000000
# 9 3 5 1.0000000
# 10 4 5 1.0000000
我们将所有成对比较扩展为具有ID值的行,我们可以将其匹配到其他可能不匹配的集合。您似乎只想获取每组点的平均距离,因此您可以执行类似这样的操作
dd <- rbind(as.data.frame(d1), as.data.frame(d2))
dd <- aggregate(dist~id1+id2, dd, mean)
现在,我们想将这个data.frame转回一个距离对象,我们需要编写另一个辅助函数。这是一次这样的功能
df2dist<-function(x, ids=1:2, vals=3, lvls=NULL) {
if(is.null(lvls)) {
lvls <- sort(unique(c(as.character(x[,ids[1]]), as.character(x[,ids[2]]))))
}
i <- as.numeric(factor(x[,ids[1]], levels=lvls))
j <- as.numeric(factor(x[,ids[2]], levels=lvls))
stopifnot(all(i<j))
n <- length(lvls)
idx <- n*(i-1) - i*(i-1)/2 + j-i
r <- rep(NA, n*(n-1)/2)
r[idx] <- x[,vals]
structure(r, class="dist", Labels=lvls, Size=n, Diag=FALSE, Upper=FALSE)
}
我们期望三列data.frame具有值对和它们之间的距离。我们可以在我们的样本上使用它来获取
df2dist(dd)
# 1 2 3 4 5
# 2 0.7500000
# 3 0.8000000 0.6666667
# 4 1.0000000 0.6666667 1.0000000
# 5 1.0000000 0.8333333 1.0000000 1.0000000
# 6 NA 0.3333333 1.0000000 1.0000000 1.0000000
所以有一些工作要转换对象以匹配标签,但它非常简单。