Markov Chains and decimal points in r?
Asked Answered
L

2

5

I have plotted a markov chain from a matrix in r. However, I have numerous probabilities under 0.01, and thus my probability plot looks something like this:

enter image description here

I've been searching for hours and I can't seem to find something that allows me to display all four decimal places. Is there any way to format this or should I leave it as is?

My code is as follows:

library(markovchain)

newtransition.matrix <- matrix( data = c(
  .9366, .0066, .0007, .0003 ,.0003, 0, .0015, 0, 
  .0583, .9172, .0225, .0026, .0006, .001, 0, 0,
  .004, .0694, .9176, .0483, .0044, .0032, .0029, 0,
  .0009, .0049, .0518, .8924, .0666, .0046, .0088, 0,
  .0002, .0006, .0049, .0444, .8323, .0572, .0191, 0,
  0, .0009, .002, .0081, .0746, .8362, .1028, 0,
  0, .0002, .0001, .0016, .0105, .0384, .6123, 0,
  0, .0002, .0004, .0023, .0107, .0594, .2526, 1),
  nrow = 8, ncol = 8,
  dimnames = list( c( "AAA", "AA", "A", "BBB", "BB", "B", "CCC", "Default" ), c( "AAA", "AA", "A", "BBB", "BB", "B", "CCC", "Default") ) )
 print( newtransition.matrix )

newtransition.matrix <- new( "markovchain", transitionMatrix = newtransition.matrix )
layout <- matrix(c(-3, 1, 2, 2, 2, -2, 4, 1, 0, 6, 0, -6, -3, -4, 3, -4), ncol = 2, byrow = TRUE)

plot(newtransition.matrix, vertex.size = 10, layout = layout, edge.arrow.size=0.25)

Many thanks!

Lohr answered 10/4, 2018 at 20:38 Comment(4)
I went through the documentation of the package at mran.revolutionanalytics.com/web/packages/markovchain/vignettes/… it seems that you can only show maximum 2 decimals. I do not know if this is acceptable but you could multiply everything by 100 or something like that?Plateau
It might be deliberate since that plot is going to get difficult to read below 2 decimals. I'd think you're better off looking at the transition matrix itself.Hooper
@Plateau multiplying everything by 100 (and thus displaying probabilities as percentages) seems like the best solution. The solutions below (as impressive as they are) are too cluttered to read.Nashbar
@John Coleman I agree that the solutions seem too cluttered with so many decimal places. There are some other packages that may be up to the task of de-cluttering things (see https://mcmap.net/q/1232113/-igraph-package-in-r-edge-labels-are-overlapping), but personally I liked your idea of using percentages.Hooknose
C
5

You need to edit the S4 methods. 2 digits limit is hard coded in the plotting function. I cannot manage to edit the body of the function with code alone (if anyone else can figure it out, leave a comment). The code below requires a bit of user input.

# Digging to find the plotting function for markovchain
showMethods(plot)

# Find the source code
f <- getMethod("plot", signature = c(x="markovchain", y="missing"))

# Ahh it uses plot.igraph, and the labels are being specified with edge.label = edgeLabel
# But edgeLabel is being rounded to 2 digits
# Extract and edit the body of f, 
# Change round(E(netMc)$weight/100, 2) to round(E(netMc)$weight/100, 4) or something larger
g <- edit(body([email protected]))

# Store the edited body again
body([email protected]) <- g

# Call new plotting function to plot with more digits
f(newtransition.matrix, vertex.size = 10, layout = layout, edge.arrow.size=0.25)

enter image description here

Continuator answered 10/4, 2018 at 21:27 Comment(1)
I like this answer very much, as the overall thought process - using showMethods() and getMethod() to investigate the behaviour of a function - is very helpful in many situations, rather than just this one.Hooknose
H
5

Here's a simple solution that uses the igraph package. If you look at the documentation for markovchain, the plotting function for markovchain simply calls the plot function from igraph, so you will find that many (if not all) of the plotting arguments are cross-compatible between both kinds of objects.

Here, we simply create an igraph object from your transition matrix, and plot that instead. You will probably find this more convenient than plotting the markovchain objects directly.

library(markovchain)
library(igraph)
newtransition.matrix <- new( "markovchain", transitionMatrix = newtransition.matrix )
layout <- matrix(c(-3, 1, 2, 2, 2, -2, 4, 1, 0, 6, 0, -6, -3, -4, 3, -4),
ncol = 2,
byrow = TRUE)

# create an igraph object from your transition matrix
graph <- as(newtransition.matrix, "igraph") 

plot(graph, vertex.size = 15,
            edge.label = E(graph)$prob, # We add the proper edge labels here
            layout = layout,
            edge.arrow.size=0.25)

enter image description here

Hooknose answered 10/4, 2018 at 21:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.