我有一个关于特定时间间隔内用户在不同状态之间转换的数据集(共9个)。这个数据集将用于一个马尔科夫链模型。总共有96个时间间隔,因此:对于每个用户有96个观测值,每个观测值都提供了指定的时间间隔、一个开始位置和一个结束位置。将两个位置结合在一起的状态,简单来说就是用户还在两个状态之间过渡。
下面是一个虚构的数据集。在这个例子中,与实际的数据集不同,开始位置和结束位置不一定是相连的,但我相信这同样可以起到说明问题的作用。
ID <- rep(1:10, each = 96)
TimeInterval <- rep(1:96, 10)
Locations <- c("Home", "Bakery", "Grocery", "Home-Bakery", "Home-Grocery", "Bakery-Home", "Bakery-Grocery", "Grocery-Home", "Grocery-Bakery")
startLocation <- sample(Locations, 960, replace = TRUE)
endLocation <- sample(Locations, 960, replace = TRUE)
df <- data.frame(ID, TimeInterval, startLocation, endLocation)
我想为每个时间间隔计算一个过渡矩阵,其中过渡概率是由给定前一个时间间隔的statelocation的过渡到一个statelocation的概率计算出来的。例如,要计算时间间隔37的过渡概率矩阵,就取在时间间隔36的状态下,在时间间隔37中处于某个状态的概率。
这将导致总共96个过渡矩阵。那么从一个状态(Location)过渡到另一个状态的概率就取决于所有用户的概率总和。
然而,我不知道如何汇总各个过渡的结果。计算这些矩阵的有效方法是什么?
每个时间间隔的过渡矩阵应该是一个包括所有状态的9x9矩阵。
编辑。
一个(非常丑陋的)dplyr解决方案 对单个过渡矩阵有效。
Interval36 <- df %>% filter(TimeInterval== 36)
Interval37 <- df %> filter(TimeInterval == 37)
timeBlock37 <- as.data.frame(cbind(Interval37$journey, Interval36$journey))
mTimeBlock37 <- as.data.frame.matrix(table(timeBlock37))
timeBlock <- prop.table(mTimeBlock37 )
timeBlock
我自己解决了这个问题,虽然不是用最优雅的方式,而是用一个非结构化的for-loop。
matrixList <- list()
states <- Locations
for(i in 1:96){
i <- ifelse(i < 96,i + 1, 96)
t1 <- df %>% filter(timeBlock == i)
j <- ifelse(i < 96,i + 1, 96)
t2 <- df%>% filter(timeBlock == j)
timeBlock <- as.data.frame(cbind(t1[,8], t2[,8]))
mTime <- as.data.frame.matrix(table(timeBlock))
timeBlock <- prop.table(mTime)
timeBlock <- as.matrix(timeBlock)
mat1 <- matrix(0, nrow = 9, ncol = 9)
colnames(mat1) <- states
rownames(mat1) <- states
colsNeeded <- colnames(mat1)[colnames(mat1) %in% colnames(timeBlock)]
rowsNeeded <- rownames(mat1)[rownames(mat1) %in% rownames(timeBlock)]
mat1[rowsNeeded, colsNeeded] <- timeBlock[rowsNeeded, colsNeeded]
matrixList[[i]] <- mat1
}
我在for-loop中创建了一个空矩阵,可以用过渡矩阵填充,以考虑到并非所有的状态都会在某个时间段内出现的情况。
如果有人还有更优雅更简洁的解决方案,欢迎贡献出来,供以后的读者参考。