我试图根据列中的分类变量计算行(数据点)之间的距离。我见过的最简单的方法是计算重叠。换句话说,变量的比例是多少,x和y取相同的值。
想象一下,我有一个数据集如下;
Id = 1:5
dummy <- data.frame(Country = c("UK", "UK", "USA", "USA", "USA"),
Category = c("Private", "Public", "Private", "Private", "Public"),
Level = c("High", "Low", "Low", "Low", "High"))
我想计算所有行对之间的比例重叠(如上所述)。
我可以定义一个函数来执行此操作;
calcOverlap <- function(Id, df) {
n <- length(Id)
results <- matrix(NA, n, n)
for(i in 1:n) {
for(j in 1:n) {
if(i > j) {
results[i, j] <- length(which(df[i,] == df[j,])) / ncol(df)
}
}
}
results
}
我觉得它有用......
dummy
calcOverlap(Id, dummy)
我的问题是,这是否已经更加整洁,更普遍地实施。更一般地说,是否存在根据分类变量计算距离度量的包。
谢谢!
答案 0 :(得分:3)
这是一种方法:
outer(seq(nrow(DF)), seq(nrow(DF)), Vectorize(function(x,y) mean(DF[x,]==DF[y,])))
[,1] [,2] [,3] [,4] [,5]
[1,] 1.0000000 0.3333333 0.3333333 0.3333333 0.3333333
[2,] 0.3333333 1.0000000 0.3333333 0.3333333 0.3333333
[3,] 0.3333333 0.3333333 1.0000000 1.0000000 0.3333333
[4,] 0.3333333 0.3333333 1.0000000 1.0000000 0.3333333
[5,] 0.3333333 0.3333333 0.3333333 0.3333333 1.0000000
但是,这会计算出比需要更多的比较。为避免这种情况,有combn
:
# values
v = combn(seq(nrow(DF)), 2, function(x) mean(DF[x[1],]==DF[x[2],]))
# [1] 0.3333333 0.3333333 0.3333333 0.3333333 0.3333333 0.3333333 0.3333333 1.0000000 0.3333333 0.3333333
# row combos
r = combn(seq(nrow(DF)), 2)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 1 1 1 2 2 2 3 3 4
# [2,] 2 3 4 5 3 4 5 4 5 5
如果你想要矩阵中的那些,那就是
m = matrix(,nrow(DF),nrow(DF))
m[t(r)] <- v
# [,1] [,2] [,3] [,4] [,5]
# [1,] NA 0.3333333 0.3333333 0.3333333 0.3333333
# [2,] NA NA 0.3333333 0.3333333 0.3333333
# [3,] NA NA NA 1.0000000 0.3333333
# [4,] NA NA NA NA 0.3333333
# [5,] NA NA NA NA NA