如何计算从一种状态到另一种状态的转换次数?

How can I count the number of transitions from one state to another?

我有以下向量

[1] 1 3 5 1 1 4 3 4 5 1 1 2 2 3 1 1 2 4 3 4 4 4 1 1 1

由以下一段代码生成

set.seed(5)
my.matrix = round(matrix(data = runif(n = 25, min = 0, max = 5), ncol = 5),0)
my.vec = as.vector(my.matrix)

我知道我可以计算每个数字的采样频率并将其存储在数据框中

freq = as.data.frame(table(my.vec))

现在假设这个向量中的每个数字都是一个状态S

How can I calculate the number of times all possible transitions from one state to the following state happened?

例如,S 从 1 到 1,从 1 到 2,从 1 到 3,等等。

我正在尝试计算一个转换矩阵,但到目前为止我执行此任务的唯一想法是使用具有 16 个不同 if 语句的 for 循环。这似乎不是最佳选择。

这是使用 1 个 for 循环的完整示例。关键是使用 expand.grid 构建所有可能的转换(请注意,您需要在 my.vec 周围使用 unique 命令,因为某些转换不止一次发生)。

获得该网格后,只需在 for 循环中逐步遍历向量,拉出当前元素和下一个元素,确定它所属的网格中的索引并将其递增 +1。代码如下。

library(dplyr)

set.seed(5)
my.matrix = round(matrix(data = runif(n = 25, min = 0, max = 5), ncol = 5),0)
my.vec = as.vector(my.matrix)


result <- expand.grid(unique(my.vec), unique(my.vec)) %>% mutate(count = 0)
for (i in 1:(length(my.vec)-1)){
  currentVal = my.vec[i]
  nextVal = my.vec[i+1]
  result[result$Var1 == currentVal & result$Var2==nextVal,]$count = result[result$Var1 == currentVal & result$Var2==nextVal,]$count +1
}

如果您想删除从未发生过渡的行:

resultNoZeros <- result %>% filter(count > 0)

通过set.seed(101); z <- sample(1:5,size=100,replace=TRUE)模拟的数据;抱歉,我没有看到您的问题中有数据生成功能...

获取所有下一步转换:table of (current) vs (next):

table(z[-length(z)],z[-1])

    1 2 3 4 5
  1 4 4 2 3 3
  2 5 4 4 3 4
  3 2 2 2 5 5
  4 4 2 5 6 7
  5 2 7 3 7 4

另一方面,如果您只想在不同状态之间转换,即在运行之间(rle= "run-length encoding"):

获取数据中每个"run"的值

v <- rle(z)$values

构建(当前值)与(下一个值)的table:

table(v[-length(v)],v[-1])

结果:

    1 2 3 4 5
  1 0 4 2 3 3
  2 5 0 4 3 4
  3 2 2 0 5 5
  4 4 2 5 0 7
  5 2 7 3 7 0

下面是可能有用的伪代码:

你有一个 25 元素 vector/array。每个元素都是从 1 到 5 的数字。为了方便起见,我们将向量称为 vec 并假设元素的索引范围为 0 到 24

你需要一个二维数组(本质上是一个矩阵),我们称它为m,这样m[0][0]就是第0行第0列(第一行第一列)。初始条件是矩阵中每个坐标的值为0

我们将在每次迭代中使用和重复使用两个变量来确定矩阵中的哪个单元格必须递增。我们称它们为 a 和 b。 a 将是每个步骤的 "from" 值,b 将是步骤的 "to" 值

  1. STEP ONE (first iteration of the for loop)

因为这是数组的第一个元素,我们只需将其值 (1) 分配给 a 并继续(结束迭代)

  1. STEPS TWO TO 25

一个。前进到向量中的下一个元素并将其值 (3) 记录在变量 b 中,此时 a = 1b = 3

b。找到第一行第三列的矩阵元素(类似于 matrix[1][3])并将其当前值 (0) 递增一个,所以现在 matrix[1][3] =1

c。在继续之前,我们需要为下一步做好准备,因此将 b 的当前值分配给 a(现在是 a = 3,因此它已准备好在下一步充当 "from"迭代)。暂时保留 b,因为它的当前值在下一次迭代之前是无关紧要的。

d。转到 for 循环的下一次迭代(移动到向量中的下一个元素(即 5)并从步骤 2a

重新开始

(此时,b 应采用当前元素值 (5),因此您转到 matrix[a][b] 并将该元素的当前值递增 1)

冲洗并重复,直到您完成 for 循环并设置好

如您所见,您根本不需要任何 if 结构...只需一个移动指针,让您可以读取数组元素的值

还有更有效的方法来做到这一点,但这应该足够了