为R

时间:2017-04-27 16:31:46

标签: r apply

我有一个从mongo数据库导入的元素数据框,示例:

#      | Mcg    | Gvh    | Alm    | Mit    | Vac    | Nuc
:----: | :----: | :----: | :----: | :----: | :----: | :----:
1      | 0.62   | 0.42   | 0.47   | 0.16   | 0.52   | 0.22
2      | 0.60   | 0.40   | 0.52   | 0.46   | 0.53   | 0.22
3      | 0.47   | 0.32   | 0.64   | 0.30   | 0.63   | 0.22
4      | 0.46   | 0.39   | 0.54   | 0.22   | 0.48   | 0.25
5      | 0.50   | 0.46   | 0.52   | 0.16   | 0.52   | 0.26

data = data.frame(
   Mcg = c(0.62, 0.60, 0.47, 0.46, 0.50),
   Gvh = c(0.42, 0.40, 0.32, 0.39, 0.46),
   Alm = c(0.47, 0.52, 0.64, 0.54, 0.52),
   Mit = c(0.16, 0.46, 0.30, 0.22, 0.16),
   Vac = c(0.52, 0.53, 0.63, 0.48, 0.52),
   Nuc = c(0.22, 0.22, 0.22, 0.25, 0.26),
   row.names = c(1:5)
)

我需要根据距离矩阵计算每对示例的共享最近邻居的数量,如果该值高于给定的阈值,请将这些示例索引保存在名为clusters的列表中。

#      | 1      | 2      | 3      | 4      | 5
:----: | :----: | :----: | :----: | :----: | :----:
1      | 0.00   | 0.31   | 0.31   | 0.19   | 0.14
2      | 0.31   | 0.00   | 0.27   | 0.28   | 0.32
3      | 0.31   | 0.27   | 0.00   | 0.21   | 0.26
4      | 0.19   | 0.28   | 0.21   | 0.00   | 0.11
5      | 0.14   | 0.32   | 0.26   | 0.11   | 0.00

dists = as.matrix(
   dist(data, method = "euclidean", diag = FALSE, upper = FALSE, p = 2)
)

我已经有一个带'for'循环的工作代码:

# get indexes of k nearest neighbors
Neighbors <- function(id, k) {
   as.integer( names( sort( dists[id, -id] )[1:k] ) )
}

threshold = 5
k = 10
clusters = vector("list", (k - threshold))

for (y in 1:(nrow(data) - 1)) {

   neighbors.e1 = Neighbors(y, k)

   for (z in (y+1):(nrow(data))) {

      neighbors.e2 = Neighbors(z, k)
      snn = sum(table(c(neighbors.e1, neighbors.e2)) == 2)

      if (snn > threshold) {
         cluster.id = snn - threshold
         if (!(y %in% clusters[[cluster.id]])) {
            clusters[[cluster.id]] = c(clusters[[cluster.id]], y)
         }
         if (!(z %in% clusters[[cluster.id]])) {
            clusters[[cluster.id]] = c(clusters[[cluster.id]], z)
         }
      }
   }
}

此解决方案非常慢。因此,我想通过使用apply函数而不是循环来优化它。

以下是完整数据集(1484行)的“群集”列表

> clusters
[[1]]
 [1]  1  3  6  7 19  2 23  8 16 17 18 20  4  5 14 21 24 15  9 10 12 22 11 13

[[2]]
 [1]  1 17 24  2  3  7  8 16 18 20  6  4 10 12 13 22  5 19 21 23  9 15 11 14

[[3]]
 [1]  4 11  7 16 19  8 18 10 12 13 14 22 20 17 24

[[4]]
[1]  5 21  7  8 18 20

[[5]]
NULL

0 个答案:

没有答案