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

时间:2018-12-05 22:25:32

标签: r for-loop if-statement counting

我有以下向量

[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

  

如何计算从一个状态到下一个状态的所有可能转换的发生次数?

例如,S经历了1次到1次,从1次到2次,从1次到3次等等。

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

3 个答案:

答案 0 :(得分:1)

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

一旦有了该网格,只需在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)

答案 1 :(得分:1)

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

要获取所有下一步转换:(当前)与(下一个)表:

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 =“运行长度编码”):

获取数据中每个“运行”的值

v <- rle(z)$values

构造一个表(当前值)与(下一个值):

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

答案 2 :(得分:1)

下面的伪代码可能会有所帮助:

您有一个25个元素的向量/数组。每个元素都是从1到5的数字。按照惯例,我们将向量称为vec,并假定元素的索引从0到24

您需要一个二维数组(本质上是一个矩阵),我们将其称为m,以便m[0][0]是第0行第0列(第一行,第一列)。初始条件是矩阵中的每个坐标的值为0

我们将在每次迭代中使用并重复使用两个变量,以确定必须递增矩阵中的哪个单元。我们将它们称为a和b。 a将成为步骤的“起始”值,b将是步骤的“起始”值

  
      
  1. 第一个步骤(for循环的第一次迭代)
  2.   

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

  
      
  1. 从两步开始到25
  2.   

a。前进到向量中的下一个元素,然后将其值(3)记录在变量ba = 1

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

c。在继续之前,我们需要为下一步做准备,因此将matrix[1][3] =1的当前值分配给b(现在为a,以便在下一次迭代中充当“ from”角色) 。由于a = 3的当前值在下一次迭代之前是无关紧要的,因此请暂时保留b

d。转到for循环的下一个迭代(移至向量中的下一个元素(为5),然后从步骤2a重新开始

(此时,b应该采用当前元素值(5),所以您转到matrix[a][b]并将该元素的当前值增加一个)

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

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

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