## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(
    echo = TRUE,
    tidy.opts = list(width.cutoff = 80),
    tidy = TRUE
)
library(anansi)
library(ggplot2)

## ----plot-krebs---------------------------------------------------------------
library(patchwork)
library(ggraph)
library(igraph)
library(tidygraph)
library(dplyr)

metabs <- c(
    "isocitrate", "cis-aconitate", "citrate", "oxaloacetate",
    "L-malate", "fumarate", "succinate", "succinyl-CoA",
    "ketoglutarate"
)
d <- data.frame(
    from = c(
        "isocitrate", "ketoglutarate", "succinyl-CoA",
        "succinate", "fumarate", "L-malate", "oxaloacetate", "citrate",
        "cis-aconitate"
    ),
    to = c(
        "ketoglutarate", "succinyl-CoA", "succinate",
        "fumarate", "L-malate", "oxaloacetate", "citrate", "cis-aconitate",
        "isocitrate"
    ),
    vertices = c(
        "isocitrate\ndehydrogenase", "ketoglutarate\ndehydrogenase",
        "succinyl-CoA\nsynthetase", "succinate\ndehydrogenase",
        "\nfumarase", "malate\ndehydrogenase", "citrate\nsynthase",
        "aconitase\n", "aconitase\n"
    )
)

krebs_layout <- data.frame(
    x = (cos(seq(2 * pi, 0, length = 10) + pi / 2) * 1.25)[c(3:9, 1:2)],
    y = (sin(seq(2 * pi, 0, length = 10) + pi / 2) * 1.25)[c(3:9, 1:2)],
    circular = FALSE,
    name = c(
        "isocitrate", "ketoglutarate", "succinyl-CoA",
        "succinate", "fumarate", "L-malate",
        "oxaloacetate", "citrate", "cis-aconitate"
    ),
    .ggraph.orig_index = 1:9,
    .ggraph.index = 1:9
)

graph_from_data_frame(d, directed = TRUE) |>
    as_tbl_graph() |>
    mutate(Legend = if_else(name %in% metabs, "Metabolite", "Enzyme")) |>
    ggraph(layout = krebs_layout) +

    geom_edge_link(
        arrow = arrow(length = unit(4, "mm"), type = "closed"),
        edge_width = 2.5, color = "black",
        end_cap = circle(11.5, "mm"),
        start_cap = circle(11.25, "mm")
    ) +

    geom_edge_link(
        aes(label = vertices),
        arrow = arrow(length = unit(4, "mm"), type = "closed"),
        edge_width = 2, color = "dodgerblue",
        end_cap = circle(11.5, "mm"),
        start_cap = circle(11.5, "mm"),
        angle_calc = "along",
        label_dodge = unit(c(rep(13, 5), rep(-13, 4)), "mm"),
        label_size = 3.15
    ) +

    geom_node_label(aes(label = name),
        size = 3.5, fill = "orange",
        show.legend = FALSE, label.padding = unit(0.4, "lines"),
        nudge_x = c(0, 0.1, 0.05, -0.05, -0.1, 0, -0.1, 0, 0.1)
    ) +

    coord_equal(
        xlim = c(-1.25, 1.25), ylim = c(-1, 1),
        ratio = 1, clip = "off"
    ) +
    theme_graph()

## ----all-v-all----------------------------------------------------------------
colmat <- data.frame(
    name = c(
        "aconitase", "isocitrate\ndehydrogenase",
        "ketoglutarate\ndehydrogenase", "succinyl-CoA\nsynthetase",
        "succinate\ndehydrogenase", "fumarase", "malate\ndehydrogenase",
        "citrate\nsynthase", "citrate", "cis-aconitate", "isocitrate",
        "ketoglutarate", "succinyl-CoA", "succinate", "fumarate", "L-malate",
        "oxaloacetate"
    ),
    y = c(seq(9, 1, length.out = 8), 9:1),
    x = rep(c(0.7, 0.3), times = c(8, 9)),
    fill = rep(c("Enzyme", "Metabolite"), times = c(8, 9))
)

p_0 <- ggplot() +
    annotate("segment",
        x = c(0.28, 0.72), y = 0.875,
        xend = c(0.28, 0.72), yend = 9.125, color = "gray"
    ) +
    geom_text(
        data = colmat, aes(y = y, x = x, label = name), colour = "black",
        size = 3.25, hjust = c(rep(0, 8), rep(1, 9)), lineheight = 7 / 10,
        nudge_x = c(rep(0.03, 8), rep(-0.03, 9))
    ) +
    scale_fill_manual(
        values = c(Metabolite = "orange", Enzyme = "dodgerblue")
    ) +
    coord_cartesian(xlim = c(1 / 20, 19 / 20), clip = "off") +
    annotate("text",
        label = c("Metabolites", "Enzymes"),
        x = c(2 / 8, 6 / 8), y = 9.6, size = 4
    ) +
    ylab(NULL) +
    xlab(NULL) +
    theme_void()

p_a <- p_0 +
    geom_point(
        data = colmat, aes(y = y, x = x, fill = fill),
        color = "black", shape = 21, size = 4, show.legend = FALSE
    )



p_b <- p_0 + geom_segment(
    data = expand.grid(seq(9, 1, length.out = 8), 9:1),
    aes(y = Var2, yend = Var1), x = 3 / 10, xend = 7 / 10,
    color = "#393D47", inherit.aes = FALSE
) +
    geom_point(
        data = colmat, aes(y = y, x = x, fill = fill),
        color = "black",
        shape = 21, size = 4, show.legend = FALSE
    )
p_c <- p_0 + geom_segment(
    data = data.frame(
        Var2 = seq(1, 9, length.out = 8)[
            c(8, 1, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1)
        ],
        Var1 =
            c(9, 9, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1)
    ),
    aes(y = Var1, yend = Var2), x = 3 / 10, xend = 7 / 10,
    color = "#393D47", inherit.aes = FALSE
) +
    geom_point(
        data = colmat, aes(y = y, x = x, fill = fill),
        color = "black", shape = 21, size = 4, show.legend = FALSE
    )

(p_b | p_c) + plot_annotation(tag_levels = "A")

## ----krebs-biadj--------------------------------------------------------------
#|

krebs_edge_df <- local({
    data("krebs", package = "anansi")
    return(krebs)
})

krebs_edge_df |>
    mutate(Enzyme = `levels<-`(
        Enzyme,
        gsub(x = levels(Enzyme), " ", replacement = "\n")
    )) |>
    ggplot() +
    geom_text(label = "X", x = I(0.5), y = I(0.5)) +
    facet_grid(Enzyme ~ Metabolite, switch = "y", space = "free_x") +
    theme_bw() +
    theme(
        strip.text.y.left = element_text(
            angle = 0, size = 10, lineheight = 7 / 10, hjust = 1
        ),
        strip.text.x.top = element_text(angle = 90, size = 10, hjust = 0),
        strip.background.x = element_rect(fill = "orange", color = "black"),
        strip.background.y = element_rect(fill = "dodgerblue", color = "black"),
        panel.spacing = unit(0.1, "lines")
    ) +
    coord_equal(ratio = 1) +
    labs(x = NULL, y = NULL)

## ----weaveWeb-intro-----------------------------------------------------------
# Two interfaces
form.web <- weaveWeb(ec ~ ko, link = kegg_link())

trad.web <- weaveWeb(y = "ec", x = "ko", link = kegg_link())

# Same output
identical(form.web, trad.web)

# Get the biadjacency matrix using the $ operator
head(dictionary(form.web), c(10, 10))

## ----peakec2ko----------------------------------------------------------------
# Extract the data.frame from the list that kegg_link() returns
ec2ko <- kegg_link()[["ec2ko"]]

head(ec2ko)

## ----names--------------------------------------------------------------------
# Note that the formula controls the order
names(weaveWeb(ko ~ ec, link = kegg_link()))

# names() is short for the above
names(weaveWeb(ec ~ ko, link = kegg_link()))

## ----weaveKEGG----------------------------------------------------------------
# Only print the first few entries
lapply(kegg_link(), head)

## ----web_formula--------------------------------------------------------------
# Formula notation
head(
    dictionary( weaveWeb(cpd ~ ko, link = kegg_link()) ), 
    c(10, 10)
)

# Character notation
head(
    dictionary( weaveWeb(y = "ko", x = "cpd", link = kegg_link()) ), 
    c(10, 10)
)

## ----AnansiWeb----------------------------------------------------------------
# Prep some dummy input tables
tX <- matrix(rnorm(30),
    nrow = 6,
    dimnames = list(NULL, x = paste("x", seq_len(5), sep = "_"))
)
tY <- matrix(rnorm(42),
    nrow = 6,
    dimnames = list(NULL, y = paste("y", seq_len(7), sep = "_"))
)

# Prep biadjacency matrix
# base::matrix is fine too, but will get coerced to Matrix::Matrix.
d <- matrix(
    data = sample(x = c(TRUE, FALSE), size = 35, replace = TRUE),
    nrow = NCOL(tY),
    ncol = NCOL(tX),
    dimnames = list(colnames(tY), colnames(tX))
)

# make the AnansiWeb
w <- AnansiWeb(
    tableY = tY,
    tableX = tX,
    dictionary = d
)

# Confirm the warning:
names(w)

## ----igraph-1, message=FALSE--------------------------------------------------
library(igraph)
# Prepared data.frame for the occasion
head(krebs_edge_df)

# Convert data.frame to graph
g <- graph_from_data_frame(krebs_edge_df, directed = FALSE)

## ----igraph-2, message=FALSE--------------------------------------------------
V(g)$type <- V(g)$name %in% krebs_edge_df$Metabolite

# Now that we've defined type, we can convert to biadjacency matrix:
bi_mat1 <- as_biadjacency_matrix(g, sparse = TRUE)


head(bi_mat1, n = c(4, 5))

## ----Matrix, message=FALSE----------------------------------------------------
library(Matrix)

# For this approach, it's useful to prepare the input as two factors:
Enzyme <- factor(krebs_edge_df$Enzyme)
Metabolite <- factor(krebs_edge_df$Metabolite)

# We can get integers out of factors, corresponding to their level indices
bi_mat2 <- sparseMatrix(
    i = as.integer(Enzyme),
    j = as.integer(Metabolite),
    dimnames = list(
        Enzyme = levels(Enzyme),
        Metabolite = levels(Metabolite)
    )
)

head(bi_mat2, n = c(4, 5))

## ----session-info-------------------------------------------------------------
sessionInfo()

