[0f2269]: / R / EnrichCirclize.R

Download this file

280 lines (252 with data), 11.8 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
#' Adjust and Export Pathway Analysis Results
#'
#' This function processes a dataframe containing fgsea results. It adjusts pathway names
#' by removing underscores, converting to lowercase, then capitalizing the first letter,
#' and joining the components with spaces. It selects and merges the top upregulated
#' and downregulated pathways based on enrichment score (ES) and p-value.
#'
#' @param fgseaRes Dataframe containing fgsea results with columns 'pathway', 'ES', and 'pval'.
#' @param nTop Integer, number of top pathways to select based on the p-value.
#' @return A vector containing combined top upregulated and downregulated pathways.
#' @importFrom Hmisc capitalize
#' @export
#' @examples
#' # Create a synthetic fgseaRes dataframe
#'fgseaRes <- data.frame(
#' pathway = c("KEGG_APOPTOSIS",
#' "GO_CELL_CYCLE",
#' "REACTOME_DNA_REPAIR",
#' "KEGG_METABOLISM",
#' "GO_TRANSPORT"),
#' ES = c(0.45, -0.22, 0.56, -0.35, 0.33),
#' pval = c(0.001, 0.02, 0.0003, 0.05, 0.01)
#')
#'
#' # Run the function to get top pathways
#'result <- adjust_export_pathway(fgseaRes = fgseaRes, nTop = 2)
#'
adjust_export_pathway <- function(fgseaRes, nTop = 10) {
# Adjust pathway names
fgseaRes$pathway <- as.character(fgseaRes$pathway)
for(i in 1:nrow(fgseaRes)){
message("Processing row ", i)
term = fgseaRes$pathway[i]
### 1. Split the string
term = unlist(strsplit(term, split="_", fixed=TRUE))[-1]
### 2. Convert to lowercase, then capitalize the first letter
term = Hmisc::capitalize(tolower(term))
### 3. Concatenate with spaces
term = paste(term, collapse=" ")
### 4. Data export
fgseaRes$pathway[i] = term
}
# Select top upregulated pathways
topPathwaysUp <- fgseaRes[fgseaRes$ES > 0,][order(fgseaRes$pval[fgseaRes$ES > 0]), 'pathway'][1:nTop]
# Select top downregulated pathways
topPathwaysDown <- fgseaRes[fgseaRes$ES < 0,][order(fgseaRes$pval[fgseaRes$ES < 0]), 'pathway'][1:nTop]
# Combine top pathways and convert any potential list to a vector
combinedPathways <- unlist(c(topPathwaysUp, rev(topPathwaysDown)), use.names = FALSE)
return(list(combinedPathways = combinedPathways, fgseaRes = fgseaRes))
}
#' Randomly Select Pathways with Limited Word Count
#'
#' This function randomly selects a specified number of pathways from a given list, ensuring that each selected pathway name does not exceed a specified number of words. It filters out pathways with names longer than the specified word limit before making the selection.
#'
#' @param pathways Character vector of pathways.
#' @param max_words Integer, maximum number of words allowed in the pathway name.
#' @param num_select Integer, number of pathways to randomly select.
#' @return A character vector of selected pathways.
#' @export
#' @examples
#' pathway_list <- c("pathway_one response to stimulus",
#' "pathway_two cell growth and death",
#' "pathway_three regulation of cellular process",
#' "pathway_four metabolic process")
#' selected_pathways <- selectPathways(pathway_list, max_words = 5, num_select = 2)
#'
selectPathways <- function(pathways, max_words = 10, num_select = 10) {
# Check input
if (!is.character(pathways)) {
stop("Please provide a character vector of pathways.")
}
# Filter pathways with word count not exceeding max_words
filtered_pathways <- pathways[sapply(pathways, function(x) length(strsplit(x, " ")[[1]]) <= max_words)]
# Randomly select num_select pathways from the filtered list
if (length(filtered_pathways) >= num_select) {
selected_pathways <- sample(filtered_pathways, num_select)
} else {
warning("Not enough pathways with <= ", max_words, " words. Returning as many as possible.")
selected_pathways <- sample(filtered_pathways, length(filtered_pathways))
}
return(selected_pathways)
}
#' Draw Dual-Sided Legends on a Plot
#'
#' This function creates two sets of legends, one on the left and one on the right side of a plot.
#' It displays color-coded legends with labels corresponding to different data categories.
#' Each legend entry consists of a colored rectangle and a text label. The left side legend has
#' text aligned to the right of the color block, while the right side legend has text aligned
#' to the left of the color block.
#'
#' @param labels Vector of labels for the legends.
#' @param colors Vector of colors corresponding to the labels.
#' @param legend_width The width of each legend viewport expressed in grid units.
#' @param x_positions Numeric vector of length 2 specifying the x-positions of the left and right legends.
#' @param y_position The y-position common for both legends, expressed as a fraction of the plot height.
#' @param just_positions List of two vectors, each specifying the horizontal and vertical justification for the legends.
#' @param text_alignments List of two character strings specifying text alignments for the legends ('left' or 'right').
#' @param font_size Numeric value specifying the font size for the legend labels.
#' @return Invisible. This function is called for its side effects of drawing legends on a plot.
#' @importFrom grid pushViewport viewport grid.roundrect grid.text upViewport unit
#' @export
#' @examples
#' labels <- c("Label1", "Label2", "Label3", "Label4", "Label5", "Label6")
#' colors <- c("#ff0000", "#00ff00", "#0000ff", "#ffff00", "#ff00ff", "#00ffff")
#'
#' # Convert to 'unit' objects for grid
#' grid::grid.roundrect(
#' x = grid::unit(0.5, "npc"), # "npc" stands for normalized parent coordinates
#' y = grid::unit(0.5, "npc"),
#' width = grid::unit(0.1, "npc"),
#' height = grid::unit(0.05, "npc"),
#' gp = grid::gpar(fill = "red"),
#' r = grid::unit(0.1, "npc") # rounding radius
#' )
#'
#' # Example of drawing legends with specific labels and colors
#' drawLegends(labels, colors, grid::unit(2, "cm"), c(0.225, 0.75), 0.5,
#' list(c("left", "center"), c("right", "center")),
#' list("right", "left"), 10)
#'
drawLegends <- function(labels, colors, legend_width, x_positions, y_position, just_positions, text_alignments, font_size) {
half_length <- length(labels) / 2
legend_height <- grid::unit(1, "lines") * half_length
# Draw left-side legend
grid::pushViewport(grid::viewport(
width = legend_width,
height = legend_height,
x = x_positions[1],
y = y_position,
just = just_positions[[1]]
))
for (i in seq_len(half_length)) {
grid::grid.roundrect(
x = grid::unit(1, "npc") - grid::unit(0.5, "cm"),
y = grid::unit(1, "npc") - grid::unit(i / half_length, "npc") + grid::unit(0.5 / half_length, "npc"),
width = grid::unit(0.7, "cm"),
height = grid::unit(0.9 / half_length, "npc"),
gp = grid::gpar(fill = colors[i], col = NA),
r = grid::unit(0.3, "snpc")
)
grid::grid.text(
labels[i],
x = grid::unit(1, "npc") - grid::unit(1, "cm"),
y = grid::unit(1, "npc") - grid::unit(i / half_length, "npc") + grid::unit(0.5 / half_length, "npc"),
gp = grid::gpar(col = colors[i], fontsize = font_size),
just = text_alignments[[1]]
)
}
grid::upViewport()
# Draw right-side legend
grid::pushViewport(grid::viewport(
width = legend_width,
height = legend_height,
x = x_positions[2],
y = y_position,
just = just_positions[[2]]
))
for (i in (half_length + 1):length(labels)) {
grid::grid.roundrect(
x = grid::unit(1, "npc") - grid::unit(0.6, "cm"),
y = grid::unit(1, "npc") - grid::unit((i - half_length) / half_length, "npc") + grid::unit(0.5 / half_length, "npc"),
width = grid::unit(0.7, "cm"),
height = grid::unit(0.9 / half_length, "npc"),
gp = grid::gpar(fill = colors[i], col = NA),
r = grid::unit(0.3, "snpc")
)
grid::grid.text(
labels[i],
x = grid::unit(1, "npc") - grid::unit(0.1, "cm"),
y = grid::unit(1, "npc") - grid::unit((i - half_length) / half_length, "npc") + grid::unit(0.5 / half_length, "npc"),
gp = grid::gpar(col = colors[i], fontsize = font_size),
just = text_alignments[[2]]
)
}
grid::upViewport()
}
#' Draw Chord Diagram with Legends
#'
#' This function creates a chord diagram from a specified dataframe and draws two sets of legends for it.
#' It adjusts the track height of the chord diagram to optimize space and uses specified colors for the grid.
#' Legends are drawn at specified positions with configurable text alignments and font sizes.
#'
#' @param all_combined_df A dataframe containing the matrix for the chord diagram.
#' @param original_colors A vector of colors for the grid columns of the chord diagram.
#' @param labels A vector of labels for the first legend.
#' @param colors A vector of colors corresponding to the first legend's labels.
#' @param labels2 A vector of labels for the second legend.
#' @param colors2 A vector of colors corresponding to the second legend's labels.
#' @param font_size The font size used for legend texts, defaults to 10.
#' @return Invisible, primarily used for its side effects of drawing on a graphics device.
#' @importFrom circlize chordDiagram
#' @importFrom grid unit
#' @importFrom graphics strwidth
#' @export
#' @examples
#' # Sample Chord Diagram Matrix
#' all_combined_df <- data.frame(
#' A = c(10, 20, 30),
#' B = c(15, 25, 35),
#' C = c(5, 10, 15)
#' )
#' rownames(all_combined_df) <- c("A", "B", "C")
#'
#' # Colors for the grid of the chord diagram (corresponding to columns of the matrix)
#' original_colors <- c("red", "green", "blue")
#'
#' # Name the colors according to the sectors (A, B, C)
#' names(original_colors) <- colnames(all_combined_df)
#'
#' # Labels and Colors for the First Legend
#' labels <- c("Label 1", "Label 2", "Label 3")
#' colors <- c("yellow", "purple", "cyan")
#'
#' # Labels and Colors for the Second Legend
#' labels2 <- c("Label A", "Label B", "Label C")
#' colors2 <- c("orange", "pink", "brown")
#'
#' # Font size for the legend texts (optional, default is 10)
#' font_size <- 10
#'
#' # Call the enrichment_circlize function with the sample data
#' # This is just an example; the plot will be rendered in an appropriate graphics context
#' # such as RStudio's plot pane or an external plotting window.
#' plot1 <- enrichment_circlize(all_combined_df,
#' original_colors,
#' labels,
#' colors,
#' labels2,
#' colors2,
#' font_size
#' )
#'
enrichment_circlize <- function(all_combined_df, original_colors, labels, colors,
labels2, colors2, font_size = 10) {
# Calculate adjusted height for the chord diagram
max_height <- max(graphics::strwidth(unlist(dimnames(all_combined_df)), "inches")) * 1.2
# Draw the chord diagram
circlize::chordDiagram(all_combined_df, grid.col = original_colors, annotationTrack = "grid",
directional = -1, direction.type = c("diffHeight", "arrows"),
link.arr.type = "big.arrow", preAllocateTracks = list(track.height = max_height))
# Draw the first set of legends
legend_width <- grid::unit(2, "cm")
x_positions <- c(0.225, 0.75)
y_position <- 0.5
just_positions <- list(c("left", "center"), c("right", "center"))
text_alignments <- list("right", "left")
drawLegends(labels, colors, legend_width, x_positions, y_position, just_positions, text_alignments, font_size)
# Draw the second set of legends
x_positions2 <- c(0.3, 0.68)
y_position2 <- 0.7
drawLegends(labels2, colors2, legend_width, x_positions2, y_position2, just_positions, text_alignments, font_size)
}