R circlize: Adjust sector size to total prevalence instead of combination frequency in Circos plot

45 Views Asked by At

I would like to draw a circos plot showing (i) all combinations in a sample through links (ii) each sector length being proportional to total frequency in the sample. How can I draw a circos plot using the circlize-package for that?

Here is an example of my dataset:

circos_df <- data.frame(
     from = c("C", "D", "D", "D", "A", "A", "A", "A", 
              "A", "F", "F", "B", "B", "B", "B"),
     to = c("E", "F", "C", "E", "B", "D", "F", "C", 
            "E", "C", "E", "D", "F", "C", "E"),
     value = c(1, 0, 0, 0, 1, 0, 1, 2, 2, 1, 4, 1, 2, 0, 1),
     total_freq = c(4, 6, 6, 6, 12, 12, 12, 12, 12, 26, 26, 4, 4, 4, 4),
     normalized_freq = c(0.1538462, 0.2307692, 0.2307692, 0.2307692, 
                         0.4615385, 0.4615385, 0.4615385, 0.4615385,
                         0.4615385,1.0000000, 1.0000000, 0.1538462,
                         0.1538462, 0.1538462, 0.1538462 ))

When I then run the following code, I receive a circos plot with sector size proportional to combination frequency:

# Create a Circos plot
chordDiagram(
  x = circos_df[, c("from", "to", "normalized_freq")],
  preAllocateTracks = list(track.height = 0.1),
  annotationTrackHeight = c(0.02, 0.1),
  annotationTrack = c("name", "grid"),
  direction.type = "arrows",
  #annotationTrackMargin = c(0.1, 0.1),
  #annotationTrackBackground = "transparent"
)

However, I was not able to create sectors with the length representing the total frequency of each letter. I have tried to draw the sectors manually using circos.initalize and circos.rect, however this did not work out or did not include the combination links anymore. I am new to R and could not find an answer in previous posts, so I would be very happy about any suggestions, thank you!

1

There are 1 best solutions below

3
Allan Cameron On

One option would be to uncount your data frame according to total frequency. This will duplicate each row an appropriate amount, meaning that the sectors will have the correct weighting applied:

library(circlize)

chordDiagram(
  x = tidyr::uncount(circos_df, total_freq)[, c("from", "to")],
  grid.col = RColorBrewer::brewer.pal(6, 'Set1'),
  preAllocateTracks = list(track.height = 0.1),
  annotationTrackHeight = c(0.02, 0.1),
  annotationTrack = c("name", "grid"),
  direction.type = "arrows"
)

enter image description here