R中从大整数到小整数的映射

mapping in R from large integer to small integers

我在 R 中有以下由节点组成的网络:

"39336" "19054" "32644" "52356" "14095" "18221" "12237" "61278" "34703" "15780" "33148" "54104" "5816"  "92819" "4"  

下面的列表描述了以节点“4”结束的所有路径

  p
[[1]]
[1] 52356 61278 19054 15780 19054 61278 19054

[[2]]
[1] 15780 19054 32644 14095 12237 19054 14095

[[3]]
[1] 32644 15780 19054 32644 12237 19054

[[4]]
[1] 19054 52356

[[5]]
[1] 19054 15780 19054 52356 61278 32644 34703 39336

[[6]]
[1] 39336 61278

[[7]]
[1] 19054 52356 61278 32644 34703 61278 18221

[[8]]
[1] 32644 18221 14095 32644 15780 39336

[[9]]
[1] 33148 18221 33148 14095 32644 12237 32644 61278

[[10]]
[1] 12237 14095 52356 12237 39336 61278

[[11]]
[1] 15780 34703 15780 34703 15780 19054

[[12]]
[1] 12237 52356 61278 12237 39336 19054 61278

[[13]]
[1] 52356 54104 32644 19054 61278 19054

[[14]]
[1] 54104 39336 61278 19054 61278 32644 39336

[[15]]
[1]  5816 54104 32644 52356 19054 52356

[[16]]
[1]  5816 19054 39336

[[17]]
[1] 19054 54104  5816 19054 52356 19054

每个子列表描述一条路径,从第一个元素开始,到'4'结束。例如,第 4 条路径从节点 19054 开始,到 52356,然后在 4 结束。

我想做的是捕获从给定起始节点开始的路径中节点参与的次数比例。

例如,如果我们查看开始一条路径的节点,我们有:

rapply(p, function(x) { head(x, 1)})

 5816 12237 15780 19054 32644 33148 39336 52356 54104 
    2     2     2     4     2     1     1     2     1 

因此,对于由节点 54104 启动的那条路径,我想为所有涉及的节点授予“1”分。换句话说,我想派生一个 table 像:

我在这里使用符号 ( n(i,j,X) ) 来表示从 i 开始,以 X 结束并涉及 j 的路径数。我有以下尝试:

   m <-matrix(0, nrow = 14, ncol= 14)

for(path in 1:length(p)){
  path <- 1
      verticesofPath <- as.integer(p[[path]])

      for (i in 2:length(verticesofPath)){
        m[verticesofPath[1], verticesofPath[i]] <- m[verticesofPath[1], verticesofPath[i]] + 1
      }

}

这里的错误是节点 id 是整数,所以我不能使用 id 作为参考将它们放在 15x15 矩阵中。如何将 ID 映射到 1-15 的整数,以便我可以跟踪在每条路径中发生了哪些节点,并能够映射回去并将 rownames/colnames 提供给作为初始节点 ID 的矩阵?

我认为一个合乎逻辑的方法是使用 id 值的索引到规范的 id 向量中作为结果矩阵的行和列索引。

match() 函数在这里很有用。您可以将节点 ID 匹配到规范 ID 向量中以检索它们在该向量中的索引,然后可以将其用作结果矩阵的行或列索引。要向后映射,您可以简单地使用行或列索引作为向量下标索引规范 ID 向量以检索原始节点 ID。

操作方法如下:

m <- matrix(0L,length(ids),length(ids),dimnames=list(from=ids,involved=ids));
for (pi in seq_along(p)) { ## iterate over all paths; pi is the path index into p
    involved <- p[[pi]][-1L]; ## get the subvector of node ids involved in (but not starting) the path
    involvedUnique <- unique(involved); ## get the unique involved ids in occurrence order
    involvedCount <- tabulate(match(involved,involvedUnique)); ## get their counts
    ri <- match(p[[pi]][1L],ids); ## compute the implicit row index of the starting node
    cis <- match(involvedUnique,ids); ## compute the implicit column indexes of the involved nodes
    m[ri,cis] <- m[ri,cis]+involvedCount; ## accrue the counts onto the result matrix
}; ## end for
m;
##        involved
## from    39336 19054 32644 52356 14095 18221 12237 61278 34703 15780 33148 54104 5816 92819 4
##   39336     0     0     0     0     0     0     0     1     0     0     0     0    0     0 0
##   19054     1     3     2     4     0     1     0     3     2     1     0     1    1     0 0
##   32644     1     2     2     0     1     1     1     0     0     2     0     0    0     0 0
##   52356     0     5     1     0     0     0     0     3     0     1     0     1    0     0 0
##   14095     0     0     0     0     0     0     0     0     0     0     0     0    0     0 0
##   18221     0     0     0     0     0     0     0     0     0     0     0     0    0     0 0
##   12237     2     1     0     2     1     0     2     3     0     0     0     0    0     0 0
##   61278     0     0     0     0     0     0     0     0     0     0     0     0    0     0 0
##   34703     0     0     0     0     0     0     0     0     0     0     0     0    0     0 0
##   15780     0     3     1     0     2     0     1     0     2     2     0     0    0     0 0
##   33148     0     0     2     0     1     1     1     1     0     0     1     0    0     0 0
##   54104     2     1     1     0     0     0     0     2     0     0     0     0    0     0 0
##   5816      1     2     1     2     0     0     0     0     0     0     0     1    0     0 0
##   92819     0     0     0     0     0     0     0     0     0     0     0     0    0     0 0
##   4         0     0     0     0     0     0     0     0     0     0     0     0    0     0 0

数据

ids <- c(39336L,19054L,32644L,52356L,14095L,18221L,12237L,61278L,34703L,15780L,33148L,54104L,
5816L,92819L,4L);
p <- list(c(52356L,61278L,19054L,15780L,19054L,61278L,19054L),c(15780L,19054L,32644L,14095L,
12237L,19054L,14095L),c(32644L,15780L,19054L,32644L,12237L,19054L),c(19054L,52356L),c(19054L,
15780L,19054L,52356L,61278L,32644L,34703L,39336L),c(39336L,61278L),c(19054L,52356L,61278L,
32644L,34703L,61278L,18221L),c(32644L,18221L,14095L,32644L,15780L,39336L),c(33148L,18221L,
33148L,14095L,32644L,12237L,32644L,61278L),c(12237L,14095L,52356L,12237L,39336L,61278L),c(
15780L,34703L,15780L,34703L,15780L,19054L),c(12237L,52356L,61278L,12237L,39336L,19054L,61278L
),c(52356L,54104L,32644L,19054L,61278L,19054L),c(54104L,39336L,61278L,19054L,61278L,32644L,
39336L),c(5816L,54104L,32644L,52356L,19054L,52356L),c(5816L,19054L,39336L),c(19054L,54104L,
5816L,19054L,52356L,19054L));

我应该澄清一下,我将维度名称和标签添加到结果矩阵纯粹是为了美观。当然可以在索引操作中使用维度名称作为下标,因此可以在索引时通过将它们强制转换为字符值来使用 id 值本身作为下标,但我建议不要这样做。我不认为到处使用 as.character() 强制转换是一种非常干净的方法,它可能会导致棘手的并发症。例如,如果您发现自己处于预字符串化 id 值的情况下,这些值可能具有略微不同的字符串表示形式,例如无关的空格、digit group separators 或前导零,那么它可能会导致索引失败。