How to combine plot with text at specific position in r - r

I want to plot a picture like this and I have finished the first half of the picture. Now the problem is how to add the below text at bottom-middle (The part of the picture circled in red. The red rectangle is just an emphasis to you and I won't show it in real picture):
For simplifying the question I used fake data:
library(tidyverse)
list <- split(mtcars, mtcars$cyl)
p <- list %>% imap(~ .x %>% ggplot(aes(x = mpg)) + geom_histogram())
plots <- ggarrange(p[[1]], p[[2]], p[[3]],
nrow = 1, ncol = 3)
text1 <- c('Category 1: Quarantinable diseases
Category 4: Vectorborne diseases
Category 7: Sexually transmitted diseases
and bloodborne infections')
text2 <- c('Category 2: Vaccine preventable diseases
Category 5: Zoonotic infections')
text3 <- c('Category 3: Gastrointestinal or
enterovirus diseases
Category 6: Bacterial infections')
text1.p <- ggparagraph(text = text1, face = "italic", size = 10, color = '#1075BC')
text2.p <- ggparagraph(text = text2, face = "italic", size = 10, color = '#EE332E')
text3.p <- ggparagraph(text = text3, face = "italic", size = 10, color = '#27B460')
Then, I combined plots with texts using ggarrange().
ggarrange(plots,
ggarrange(text1.p, text2.p, text3.p, ncol = 3, nrow = 2),
ncol = 1, nrow = 2
)
The result was not what I wanted. The text was evenly distributed in the second row not at bottom-middle. To make both sides of the text blank, I add two NA in ggarrange() but failed.
ggarrange(plots,
NA,
ggarrange(text1.p, text2.p, text3.p, ncol = 3, nrow = 2),
NA,
ncol = 1, nrow = 2
)
Also, the text didn't align as the picture I posted. For solving this I got an idea but don't know how to do it. I want to store the text into a datafram with different columns and then combine plots with the datafram. But I don't know how to do it.
text_df <- structure(list(group = c("Category 1:", "Category 4:", "Category 7:",
NA, "Category 2:", "Category 5:", "Category 3:", NA, "Category 6:"
), text = c("Quarantinable diseases", "Vectorborne diseases",
"Sexually transmitted diseases", "and bloodborne infections",
"Vaccine preventable diseases", "Zoonotic infections", "Gastrointestinal or",
"enterovirus diseases", "Bacterial infections"), color = c("#1075BC",
"#1075BC", "#1075BC", "#1075BC", "#EE332E", "#EE332E", "#27B460",
"#27B460", "#27B460")), row.names = c(NA, -9L), class = c("tbl_df",
"tbl", "data.frame"))
Any help will be highly appreciated! :)

Related

How to adjust column width in dataframe of foretsplotter function

I am trying to create a forestplot, using forestplotter function, am able to get a beautiful graph, but am not able to see the entire graph, the column widths in few of the columns are so big, even if the string size is less, making the width of the entire graph, so big to see, can someone help me with this and also is it possible to align the datahrame contents uniformly centre aligned......Please help me with this
The code and relevant data are
###Required packages###
library(grid)
library(forestploter)
library(rmeta)
library(gridExtra)
#Data entered#
df <- data.frame(Study=c("A","B","C","D","Summary"),
nA = c(24,187,36,26,273),
median_A = c(4.9,5.69,8.866995074,8.5,NA),
Q1A =c(3,2.86,4.495073892,2,NA),
Q3A =c(8.5,9.78,14.96305419,32,NA),
nP = c(23,193,36,26,278),
median_P = c(7.2,6.79,8.990147783,12.5,NA),
Q1P =c(3.4,3.59,4.002463054,2,NA),
Q3P =c(10.9,10.12,12.06896552,43,NA),
W = c("10.6%","80.8%","8.0%","0.70%",NA),
E=c(-2.3,-1.1,-0.123152709,-4,-1.16881587),
UL=c(1.161473203,0.156288294,3.881699516,10.02689306,-0.039791047),
LL=c(-5.761473203,-2.356288294,-4.128004935,-18.02689306,-2.297840692))
#Calculate SE for box size#
df$SE <- (df$UL-df$E)/1.96
#Column for Confidence intervals for Drug A and Placebo, with 2 significant digit#
df$IQRA <- sprintf("%.2f (%.2f to %.2f)",df$median_A,df$Q1A, df$Q3A)
df$IQRP <- sprintf("%.2f (%.2f to %.2f)",df$median_P,df$Q1P, df$Q3P)
#Column for Confidence intervals for NET EFFECT, with 2 significant digit#
df$MD <- sprintf("%.2f (%.2f to %.2f)", df$E, df$LL, df$UL)
#Create a column with space for forest plot#
df$" "<- paste(rep(" ", 16), collapse = " ")
##Forest plot theme##
#To be modified as needed#
ftn <-forest_theme(
base_size = 16,
base_family = "serif",
ci_pch = 15,
ci_col = "black",
ci_lty = 1,
ci_lwd = 1,
ci_Theight = 0.25,
legend_name = " ",
legend_position = "right",legend_value = "",
xaxis_lwd = 1,
xaxis_cex = 0.7,
refline_lwd = 1,
refline_lty = "dashed",
refline_col = "red",
summary_fill = "blue",
summary_col = "blue",
footnote_cex = 0.4,
footnote_fontface = "plain",
footnote_col = "black",
title_just = c("center"),
title_cex = 1.1,
title_fontface = "bold",
title_col = "black",
show.rownames = FALSE)
##Table in Order for Forest plot##
#First get Column names#
colnames(df)
df2 <-df[,c(1,2,15,6,16,18,17)]
#Make NA cells empty
df2[5,3] <-c(" ")
df2[5,5] <-c(" ")
##Forestplot##
plot<-forest(df2,
est = df$E,
lower = df$LL,
upper = df$UL,
sizes = (df$SE/10),
ci_column = 6,
ref_line = 0,
arrow_lab = c("Drug A Better", "Placebo Better"),
xlim = c(-7, 6),
is_summary = c(FALSE,FALSE,FALSE,FALSE,TRUE),
xlog = FALSE,
ticks_digits = 0,ticks_at = c(-6,0,6),
theme = ftn)
##Show plot
print(plot, autofit = FALSE)

In R language with (reactable) How to align all bars for different values when using data_bars() and setting text_position = "outside-base"

I want to align all bars to appear in a nice way and not too missy for the columns when I am using data_bars() for a column inside reactable().. when the value is less than 10. the bar appears to the left of others with value > 10. because it starts after the intergers when I position then outside-base. I want exactly to position the numbers outside-base but the bars appears in a consistent way.
I provide a simple r code here.
data <- data.frame(
Group = c("Red Group 1","Red Group 2","Red Group 3","Red Group 4","Red Group 5",
"Blue Group 1","Blue Group 2","Blue Group 3","Blue Group 4","Blue Group 5",
"Green Group 1","Green Group 2","Green Group 3","Green Group 4","Green Group 5"),
Pct1 = c(.27, .82, .044, .68, .78,
.74, .66, .33, .23, .02,
.50, .055, .40, .70, .60),
Pct2 = c(.33, .17, .87, .54, .037,
.84, .72, .061, .48, .077,
.01, .39, .60, .55, .81)
)
reactable(
data,
pagination = FALSE,
defaultColDef = colDef(
cell = data_bars(data,
text_position = "outside-base",
number_fmt = scales::percent)
)
)
text_position = 'inside-base' would make it a bit less messy, might want to use a different text color ...

Loop functions with multiple variables for ggplot2

I want to build several plots from one large database, so that I have one plot for each Text (factor) and for each Measure (the many resulting measures of an eye tracking study). The following is a much simpler example of what I am trying to to:
Let's say this is my dataset
Text <- c(1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2)
Position <- c(1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4)
Modified <- c(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0)
Line_on_page <- c(1, 1, 1, 1, 2,2,2,2 ,1 ,1,1,1,2,2,2,2)
IA_FIXATION_DURATION <- c(250.3, 70.82, 400, 120.12, 270, 120.5, 100.54, 212.43, 250.3, 70.82, 320.29, 123.12, 260, 121.5, 100.54, 272.43)
IA_FIXATION_COUNT <- c(1,0,1,1,3,2,0, 1, 1,0,1,2,3,2,0, 2)
IA_LABEL <- c("she", "did", "not", "know", "what", "to", "say", "to", "she", "did", "not", "know", "what", "to", "do", "to")
testDF <- data.frame(Text , Position , Line_on_page, Modified, IA_FIXATION_DURATION, IA_FIXATION_COUNT, IA_LABEL)
so I want a heatmap (or another graph) for each Text (1/2/3), and for each measure (IA_FIXATION_DURATION/IA_FIXATION_COUNT)
# so first i create my vectors
library(stringr)
library(reshape2)
library(ggplot2)
library(ggthemes)
library(tidyverse)
Text_list <- unique(testDF$Text)
Measure_list <- testDF %>% dplyr::select_if(is.numeric) %>% colnames() %>% as.vector()
# create graphing function
Heatmap_FN <- function(testDF, na.rm = TRUE, ...){
# create for loop to produce ggplot2 graphs
for (i in seq_along(Text_list)) {
for (j in seq_along(Measure_list)) {
# create plot for each text in dataset
plots <- ggplot(subset(testDF, testDF$Text==Text_list[i])) +
geom_tile(aes(x=Position,
y=Line_on_page,
fill = Measure_list[j])) +
geom_text(aes(x=Position,
y=Line_on_page,
label=IA_LABEL),
color = "white", size = 2, family = "sans") +
scale_fill_viridis_c(option = "C", na.value = "black") +
scale_y_reverse() +
facet_grid(Page ~ Modified)+
theme(legend.position = "bottom") +
ggtitle(paste(Text_list[i],j, 'Text \n'))
ggsave(plots, file=paste(Measure_list[j], "_T", Text_list[i], ".pdf", sep = ""), height = 8.27, width = 11.69, units = c("in"))
}
}
}
Heatmap_FN(testDF)
now, I am pretty sure that the problem lies in the geom_tile "fill" part, where I would like to indicate to the function that I want to use the results variables one by one to produce the plot.
Any ideas on how to fix that?
Thanks

Plotting a network using ggplot using data from one file and color coding using another

I have a problem most likely with a simple solution. I have two data frames. The first is a simple edge list with weights that looks like this:
head(merge_allwinsloss_df)
winner loser weight
1 CAL HAW 20
2 TENN APP 7
3 LOU CHAR 56
4 CMU PRE 46
5 WAKE TULN 4
6 CIN UTM 21
and the second is a file that provides groupings (in the form of college football conferences) that looks like this:
short conference
1 TEM AAC
2 USF AAC
3 UCF AAC
4 CIN AAC
5 ECU AAC
6 CONN AAC
What I'd like to do is to create a plot (preferably using ggplot) that uses a directed graph (from winner to loser), weight the edges (via weight) and color those by teams in the same conference, and color code nodes by conference. The code below is a "start" but I'm not really getting anywhere.
ggplot(data = merge_allwinsloss_df, aes(from_id = winner, to_id = loser)) +
geom_net(aes(color = all_teams_by_conference_df), layout.alg = "fruchtermanreingold",
size = 2, labelon = TRUE, vjust = -0.6, ecolour = "grey80",
directed = TRUE, fontsize = 3, ealpha = 0.5) +
scale_color_brewer("Conference",
palette = "Paired") +
xlim(c(-0.05, 1.05)) +
theme_net() +
theme(legend.position = "bottom")
I melted the data but that also caused a lot of other problems mostly associated with either losing the mapping or my inability to figure out how to tag the teams in merge_allwinsloss_df by conference properly. I'm sorry if this isn't overtly clear. I've been searching for help and racking my brain for days so any help would get greatly appreciated. Thanks in advance.
UPDATE: Here is a minimal example.
#Create a list of CFB winners and losers with weight given by point differential
merge_allwinsloss_ALT_df <- data.frame(matrix(c("CAL","HAW", 12, "TENN", "APP", 7, "LOU", "CHAR", 56,
"CMU", "HAW", 0, "WVU", "APP", 20 , "ARK", "TENN", 6, "CMU", "WVU", 7,
"WVU", "JMU", 15, "IND", "MIN", 3, "IND", "HAW", 14, "FSU", "TCU", 2,
"TCU", "ARK", 14),
nrow=12,ncol=3,byrow=TRUE))
colnames(merge_allwinsloss_ALT_df) <- c("winner", "loser", "weight")
merge_allwinsloss_ALT_df
#Create a list of CFB teams with conference associations
all_teams_by_conference_ALT_df<- data.frame(matrix(c("CAL","PAC", "HAW", "MAC", "TENN", "SEC",
"APP", "SUN BELT", "LOU", "ACC", "CHAR", "FCS",
"CMU", "MAC", "WVU", "BIG 12", "ARK", "SEC", "JMU", "FCS",
"IND", "BIG 10", "MIN", "BIG 10", "FSU", "ACC", "TCU",
"BIG 12"),
nrow=14,ncol=2,byrow=TRUE))
colnames(all_teams_by_conference_ALT_df) <- c("team", "conference")
all_teams_by_conference_ALT_df
# (attempt to) Plot the two data files using the first as the nodes and the # second as a reference file for coloring by conference.
ggplot(data = merge_allwinsloss_ALT_df, aes(from_id = winner, to_id = loser)) +
geom_net(aes(color = all_teams_by_conference_ALT_df), layout.alg = "fruchtermanreingold",
size = 2, labelon = TRUE, vjust = -0.6, ecolour = "grey80",
directed = TRUE, fontsize = 3, ealpha = 0.5) +
scale_color_brewer("Conference",
palette = "Paired") +
xlim(c(-0.05, 1.05)) +
theme_net() +
theme(legend.position = "bottom")
I realize that something is off here but I just can't figure it out. Moreover, I'd like to set it up so that (a) all of the teams in the same conference that have played against each other share a common color for their edges and (b) weight the edges using the weight column in merge_allwinsloss_df_ALT.
Thank you for the help!
You need to join the two tables together so that it's all in one data frame.
To add the conference of the winner, you'd do it as follows:
df1 <- merge(merge_allwinsloss_ALT_df,all_teams_by_conference_ALT_df,
by.x="winner",by.y="team",all.x=T)
To capture both the winning and losing teams' conferences, then I'd rename df1$conference to "conference_winner", and then perform the same merge again this time using df1, and by.x="loser"
Also, I'd suggest trying to use shorter names for your data frames. It doesn't make sense to type merge_allwinsloss_ALT_df over and over. Also merge is a function, so that compounds the problem by creating confusion when you use it in a name (see above where my code is merge(merge...) due your naming convention).
After that you can just map color and/or fill to conference_winner or conference_loser.

How do i get one item per row in a timevis gantt chart?

I am working with the timevis library in R. I want a gannt diagram with one line per item. The following example will stack items after another if there is room. Is there a way to force the diagram to have as many rows as there are items?
library(timevis)
data <- data.frame(
id = 1:4,
content = c("Item one" , "Item two" ,"Ranged item", "Item four"),
start = c("2016-01-10", "2016-01-11", "2016-01-20", "2016-02-14"),
end = c(NA , NA, "2016-02-04", NA)
)
timevis(data)
This gives the following output from timevis:
But I want each of the items on a separate line
I am aware of other packages than timevis, but I would prefer using timvis as the interactivity is very usefull for what I am trying to vizualise.
From the examples, slightly modified:
timevis(data = data.frame(
start = c(Sys.Date(), Sys.Date()+1, Sys.Date() + 2, Sys.Date() + 3),
content = c("one", "two", "three", "four"),
group = c(1, 2, 3, 4)),
groups = data.frame(id = 1:4, content = c("G1", "G2", "G3", "G4"))
)
This should be a good starting point.
You need the option: stack = TRUE for this, this puts them on different lines inside a group, example final call below
tv <<- timevis(main,group, showZoom = FALSE,options = list(
editable = TRUE,stack = TRUE, showCurrentTime = FALSE,multiselect = TRUE,align = "center"))

Resources