计算R中分类变量的重叠(和距离度量)

时间:2015-10-27 15:06:26

标签: r distance categorical-data

我试图根据列中的分类变量计算行(数据点)之间的距离。我见过的最简单的方法是计算重叠。换句话说,变量的比例是多少,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)

我的问题是,这是否已经更加整洁,更普遍地实施。更一般地说,是否存在根据分类变量计算距离度量的包。

谢谢!

1 个答案:

答案 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