I will start define a vector of values like this:
data <- c(2.3, 1.7, 1.7, 1.4, 1.7, 2.0, 2.2, 1.8, 1.7, 1.6, 2.0, 1.5, 1.1, 1.4, 1.8, 2.0, 1.5, 1.2, 1.0, 1.2, 1.5, 1.6, 1.1,
1.5, 2.0, 2.1, 2.1, 2.0, 1.7, 1.7, 1.7, 1.3, 0.8, -0.1, 0.0, -0.1, -0.2, 0.0, 0.1, 0.2, 0.2, 0.0, 0.2, 0.5, 0.7, 1.4,
1.0, 0.9, 1.1, 1.0, 1.0, 0.8, 1.1, 1.5, 1.6, 1.7, 2.1, 2.5, 2.7, 2.4, 2.2, 1.9, 1.6, 1.7, 1.9, 2.2, 2.0, 2.2, 2.1,
2.1, 2.2, 2.4, 2.5, 2.8, 2.9, 2.9, 2.7, 2.3, 2.5, 2.2, 1.9, 1.6, 1.5, 1.9, 2.0, 1.8, 1.6, 1.8, 1.7, 1.7, 1.8, 2.1,
2.3, 2.5, 2.3, 1.5, 0.3, 0.1, 0.6, 1.0, 1.3, 1.4, 1.2, 1.2, 1.4, 1.4, 1.7, 2.6, 4.2, 5.0, 5.4, 5.4, 5.3, 5.4, 6.2,
6.8, 7.0, 7.5, 7.9, 8.5, 8.3, 8.6, 9.1, 8.5, 8.3, 8.2, 7.7, 7.1, 6.5, 6.4, 6.0, 5.0, 4.9, 4.0, 3.0, 3.2, 3.7, 3.7)
And From this vector I make an ifelse statement to represent its "Increase", "Decrease", and "Stagnant"
direction <- c(0,diff(data))
direction_states <- ifelse(direction > 0, "Increase", ifelse(direction < 0, "Decrease", "Stagnant"))
And finally have a dataframe from these 2 respective keys:
df_track <- as.data.frame(cbind(data, direction_states))
df_track <- df_track[-1,]
This is how i constructed a First Order Markov Chain using the package markovchain
library(markovchain)
direction_states_diff <- c(df_track$direction_states[2:nrow(df_track)])
transition_matrix <- as.matrix(table(df_track$direction_states[1:length(direction_states_diff)], direction_states_diff) / rowSums(table(df_track$direction_states[1:length(direction_states_diff)], direction_states_diff)))
transition_matrix <- as.numeric(transition_matrix)
dim(transition_matrix) <- c(3, 3)
transition_matrix[is.na(transition_matrix)] <- 0
markov_chain <- new("markovchain", states = c("Decrease", "Increase", "Stagnant"),
transitionMatrix = transition_matrix, name = "Markov 1st Order Value")
print(markov_chain)
Decrease Increase Stagnant
Decrease 0.5614035 0.3333333 0.10526316
Increase 0.2537313 0.6567164 0.08955224
Stagnant 0.5833333 0.3333333 0.08333333
set.seed(123)
simulated_states <- rmarkovchain(n = 10, object = markov_chain, t0 = tail(df_track$direction_states, 1))
print(simulated_states)
But I am unable to reproduce an example to make 2nd or Higher Markov Model, since this statements:
markov_chain <- new("markovchain", states = c("Decrease", "Increase", "Stagnant"),
transitionMatrix = transition_matrix, name = "Markov 1st Order Value")
Only allows me an input of 2D Matrix, not 3D or above. showing an error like this:
Error in validObject(.Object) :
invalid class “markovchain” object: invalid object for slot "transitionMatrix" in class "markovchain": got class "array", should be or extend class "matrix"
Help is Appreciated!
I think i just found the answers, there is this function called fitHigherOrder()
in the markovchain
package, when I try to execute it like this:
high_order4 <- fitHigherOrder(df_track$direction_states, 4) #using 4 orders
I get these results:
$lambda
[1] 2.026152e-08 3.087294e-07 9.999995e-01 1.391219e-07
$Q
$Q[[1]]
Decrease Increase Stagnant
Decrease 0.5614035 0.25373134 0.58333333
Increase 0.3333333 0.65671642 0.33333333
Stagnant 0.1052632 0.08955224 0.08333333
$Q[[2]]
Decrease Increase Stagnant
Decrease 0.47368421 0.3787879 0.33333333
Increase 0.49122807 0.4848485 0.58333333
Stagnant 0.03508772 0.1363636 0.08333333
$Q[[3]]
Decrease Increase Stagnant
Decrease 0.4035088 0.46153846 0.16666667
Increase 0.4912281 0.46153846 0.75000000
Stagnant 0.1052632 0.07692308 0.08333333
$Q[[4]]
Decrease Increase Stagnant
Decrease 0.42857143 0.44615385 0.16666667
Increase 0.48214286 0.46153846 0.75000000
Stagnant 0.08928571 0.09230769 0.08333333
$X
Decrease Increase Stagnant
0.41605839 0.48905109 0.09489051
That Q[[1]]
is almost the same as the result of First Order Markov Chain above except this one printed a column-wise results (that sums into a probability of 1) while above First Order Markov Chain printed a row-wise results. Hence if I do this, I can reproduce it:
for(g in 1:length(order4$Q)){
order4$Q[[g]] <- t(order4$Q[[g]])
}
markov_chain_order2 <- new("markovchain", states = c("Decrease", "Increase", "Stagnant"),
transitionMatrix = order4$Q[[2]], name = "Markov 2nd Order Value")
print(markov_chain_order2)
set.seed(123) # for reproducibility
simulated_states <- rmarkovchain(n = 10, object = markov_chain_order2, t0 = tail(df_track$direction_states, 1))
print(simulated_states)
If by Q[[2]] and above represents its second order Markov Chain probabilites or above in 2D Matrix. (Still, Correct me if I am wrong)