Let data reach limits in ggplot instead of going NA - r

I'm attempting to plot some standard error (SE) bars using ggplot2. In this set-up, I have thick bars displaying typical SE bars, but on top of those bars, I overlay thin bars showing "alternative" SEs (which are under the heading "se2" in the data). These alternative SE bars are always larger than the data.
The issue that I'm running into is that the large alternative SEs get removed, with the warning message telling me that 2 rows are removed since they were containing missing values. What I would like is simply for these values to be displayed anyway, where if the alternative SE bar reaches the limit I've set, then it stops there, still showing up (with the implication for the reader then that it continues past).
I've posted a simplified version of what I'm working with:
# Load packages
library(dplyr)
library(ggplot2)
library(ggpubr)
# Make dataframe for group 1
df_values1 <- data.frame(
beta = c(0.07,0.04,0.3),
se = c(.01,0.01,0.008),
se2 = c(0.1,0.05,0.2),
outcome = c("Name 1",
"Name 2",
"Name 3"),
sample = c(rep("Group1",3))
)
# Make dataframe for group 2
df_values2 <- data.frame(
beta = c(0.15,-0.04,0.03),
se = c(.01,0.01,0.008),
se2 = c(0.1,.2,0.05),
outcome = c("Name 1",
"Name 2",
"Name 3"),
sample = c(rep("Group2",3))
)
# Make dataframe for group 3
df_values3 <- data.frame(
beta = c(0.22,0.18,-0.03),
se = c(.01,0.01,0.008),
se2 = c(1,0.05,0.01),
outcome = c("Name 1",
"Name 2",
"Name 3"),
sample = c(rep("Group3",3))
)
# Position dodge
pd <- position_dodge(0.7)
# Merge datasets
df_all <- rbind(df_values1, df_values2, df_values3)
# NOTE: use the levels of outcome from one of the non-merged datasets
df_all$outcome <- factor(df_all$outcome, levels = df_values1$outcome)
# Because the coordinates will be flipped, the order of the levels is 'reversed' here
df_all$sample <- factor(df_all$sample, levels = c('Group3', 'Group2', 'Group1'))
# Plot
picture <- ggplot(df_all, aes(x = outcome, y = beta, group = sample, colour = sample)) +
geom_hline(yintercept = c(-0.375, -0.125, 0.125, 0.375), size = 0.25, colour = 'grey95') +
geom_errorbar(aes(ymin = beta-1.96*se, ymax = beta+1.96*se), width = 0, alpha = 1, size = 2, position = pd) +
geom_errorbar(aes(ymin = beta-1.96*se2, ymax = beta+1.96*se2), width = 0, alpha = 1, size = 0.5, position = pd) +
geom_hline(yintercept = 0, size = 0.25) +
guides(colour = guide_legend(reverse = TRUE), shape = guide_legend(reverse = TRUE)) +
ylim(-0.5,0.5) +
coord_flip() +
scale_x_discrete(limits = rev(levels(df_all$outcome)))
picture
Here is the picture of the result
I'm hoping there's a solution that will accommodate both situations in the example above: 1) the pink alternative SEs for "Name 1" are too large, so ideally they would be from end-to-end of the graph; 2) the blue alternative SEs for "Name 3" are too large on the right but on the left should stop within the plot. So on the left it stops in the plot but on the right continues until it hits the limit. Thanks!

See both answers here: How to set limits for axes in ggplot2 R plots? Normally coord_cartesian is used to prevent data being clipped but if you are using coord_flip then limits can be set within this:
picture <- ggplot(df_all, aes(x = outcome, y = beta, group = sample, colour = sample)) +
geom_hline(yintercept = c(-0.375, -0.125, 0.125, 0.375), size = 0.25, colour = 'grey95') +
geom_errorbar(aes(ymin = beta-1.96*se, ymax = beta+1.96*se), width = 0, alpha = 1, size = 2, position = pd) +
geom_errorbar(aes(ymin = beta-1.96*se2, ymax = beta+1.96*se2), width = 0, alpha = 1, size = 0.5, position = pd) +
geom_hline(yintercept = 0, size = 0.25) +
guides(colour = guide_legend(reverse = TRUE), shape = guide_legend(reverse = TRUE)) +
coord_flip(ylim = c(-0.5,0.5)) +
scale_x_discrete(limits = rev(levels(df_all$outcome)))

Related

How to create a different vline for 3 conditions?

I am trying to get a vline on a predicted plot until the sjplot::plot_model function. I have a paneled graph and for each condition (baseline, autonomous and fairness) I have a different vline I want to depict. Basically the point of divergence when the CI bands no longer overlap.
The issue I have is that I can get the lines on there, but it's all three lines for each panel rather than a unique line for each panel.
Here is the code I use to create my model
model3 <- glmer (reject ~ (1|sn) + condition*dist*actor.age.years +
block + actor.gender,
data = en.long.ai, family = binomial,
nAGQ = 1,
control = glmerControl(optimizer = "optimx", optCtrl = list(method = "bobyqa")))
then I do this to create my plot
ai.pred.plot <- sjPlot::plot_model(model3, type = "pred", terms = c( "actor.age.years", "dist", "condition"), title = "AI: Predicted probability of rejections",
se = TRUE,
legend.title = "allocation type",
show.data = F,
colors = "Set2")
print (ai.pred.plot + labs(y = "Probability of rejection") + labs(x = "Age (years)"))
Here is what I get.
predicted plot of rejections by condition and age
Then I try to make the vline. I've tried many methods....
#create a data frame
#one attempt
Primary<- c(6.6, 7.4, 4.75 )
grid <- c("Basline", "Autonomous", "Fairness")
treat<- data.frame(grid, Primary,stringsAsFactors = F)
#another attempt
vline.data <- data.frame(z = 6.6, 7.2, 4.5), condition = c("Baseline","Autonomous","Fariness"))
vline.data <- data.frame(condition = ("Baseline", z = 6.6), ("Autonomous", z = 7.2), ("Fariness", z = 7.2))
# then I try to add it to the plot
ai.pred.plot + geom_vline(aes(xintercept = z), vline.data, linetype = "dashed", color = "grey30") +
guides(fill = FALSE)
#or
print (ai.pred.plot + geom_vline(data=treat,aes(xintercept = Primary), linetype = "dotdash") )
I always get this.
predicted plot with 3 vlines
but I want one line per panel.
please help.

set x axis on ggtree heatmap in R

I would like to set x axis on a heatmap ggtree.
This is my code
ggtree(working_tree,open.angle=15, size=0.1) %<+% avian %<+% color +
aes(color = I(colour)) +
geom_tippoint(size = 2,) +
geom_tiplab(size = 3, colour = "black") +
theme_tree2()
# I want to rotate the x axis and get the positive number
p1 <- revts(p) + scale_x_continuous(labels = abs)
h1 <- gheatmap(p1, landuse,
offset = 15, width = 0.05, font.size = 3, colnames_position = "top", colnames_angle = 0,
colnames_offset_y = 0, hjust = 0) +
scale_fill_manual(breaks = c("Forest", "Jungle rubber", "Rubber", "Oil palm"),
values = c("#458B00", "#76EE00", "#1874CD", "#00BFFF"), name = "Land use system",
na.value = "white")
, and I got this picture
The problem is that when I showed the heatmap, the x axis automatically changes the range itself from 0 to 60. However, the range I want is from 0 to 80.
Does anyone know how to do this or have any experiences for this?
Updated
I already solved the case by using the function scale_x_continous like this
scale_x_continuous(breaks = seq(-80,0,20), labels = abs(seq(-80,0,20)))
For anyone interested in geological timescale in R, I suggest to use the package deeptime

Plotting range for same variable across two conditions

I have an input matrix consists of 5 columns and 12 rows.
I am trying to plot a range for same variables (lets say width) across two methods/conditions (Paper, estimated). I am able to plot range across one methods/condition using code:
Input <- read.table("File.txt", header = T, sep = "\t")
ggplot(Input, aes(x=Trait))+
geom_linerange(aes(ymin=min,ymax=max),linetype=3,color="Black")+
geom_point(aes(y=min),size=3,color="darkgreen")+
geom_point(aes(y=max),size=3,color="darkgreen")+ labs(y="-log10(P)", x="Traits") +
theme_bw()
But I want to plot each variable across methods together in the same plot. I can do this by adding an extra suffix with each variable Is there a nicer way to do this? I have tried shape=Method but it's not working for me, Any help will be highly appreciated.
I would suggest mapping Method on color instead of shape. But hey. It's your plot. (; To achieve your desired result without adding a suffix you could make use of position_dodge like so:
library(tibble)
library(ggplot2)
ggplot(Input, aes(x = Trait, shape = Method)) +
geom_linerange(aes(ymin = min, ymax = max, group = Method), linetype = 3, color = "Black", position = position_dodge(.6)) +
geom_point(aes(y = min), color = "darkgreen", size = 3, position = position_dodge(.6)) +
geom_point(aes(y = max), color = "darkgreen", size = 3, position = position_dodge(.6)) +
labs(y = "-log10(P)", x = "Traits") +
theme_bw()
DATA
set.seed(42)
Input <- tibble(
Method = rep(c("Paper", "Estimated"), each = 3),
Trait = rep(c("Width", "Density", "Lenght"), 2),
Count = rep(c(2, 4, 10), 2),
min = runif(6, 5, 7),
max = min + runif(6, 0, 10)
)

Is there a way in R to insert a bar graph into a table?

I cannot figure out how to insert a graph into my table such that each row of my graph aligns with each row of my table.
Here is an example of some data to play with:
library(survival)
df <- data.frame(futime = abs(rnorm(1000, mean = 5, sd = 5)),
outcome = sample(c(0, 1), replace = TRUE, size = 1000),
variable1 = factor(sample(c(0, 1), replace = TRUE, size = 1000)))
fit.coxph <- coxph(Surv(time = futime, event = outcome) ~ variable1, data = df)
I am trying to achieve something like the figure created by ggforest.
ggforest(fit.coxph)
The reason I don't want to use ggforest is because I want to do further customisation of the figure. I can already create the graph (code below), I'm just trying to work out how to insert this into a table.
df1 <- data.frame(Name = "Variable 1",
Ratio = exp(coef(fit.coxph)),
CI = exp(confint(fit.coxph)))
ggplot(df1,
aes(x = rownames(df1), y = Ratio, ymin = CI.2.5.., ymax = CI.97.5..)) +
geom_pointrange() +
geom_hline(yintercept = 1, linetype = 2) +
scale_y_continuous((trans = "log2")) +
geom_errorbar(width = 0.2) +
coord_flip()

CI display for ggplot2

I have a matrix that looks like
m = structure(c(323.779052983988, 468.515895704753, 587.268448071498,
701.348128517059, 779.979804648318, 727.214175106036, 907.318055915511,
1115.76665653904, 256.756620668571, 402.701329692437, 487.179245291945,
490.318053207526, 654.076130682292, 637.123436099074, 722.662552444773,
792.505947658499, 403.652330928532, 577.534367257774, 900.565634583409,
920.152416244856, 2357.72405145892, 3587.16328098826, 1452.70178195117,
1579.28418044468, 338.358847483685, 454.199083058843, 599.97279688233,
700.985565850218, 741.316909631413, 801.287026382171, 922.197411647728,
1114.06641511944, 291.406778366111, 395.588263809182, 605.249603657004,
499.747863299406, 535.230373829629, 542.056360622003, 796.821508497618,
765.755975092841, 385.004883847313, 658.784861034504, 822.223611208372,
1145.62924659969, 874.330710055459, 2138.50154766236, 1622.81483333837,
5233.38890249983, 326.628586231411, 475.233191752907, 584.49028480417,
700.341240251852, 786.302433055766, 900.413365602976, 964.629943008088,
1028.82949413297, 338.629636961477, 488.195412653447, 587.800574630787,
716.597816045267, 822.268333195828, 998.509804262574, 1037.41705762635,
1070.88757066892, 365.518529559524, 545.02881088877, 675.193759918472,
850.711841186985, 1006.39383294974, 1155.64170488707, 1318.06948607024,
1382.22753306512, 326.238411688287, 468.96417383265, 579.601628485875,
687.695555889267, 781.084920045155, 873.426833221962, 951.816393171732,
1040.03875034591, 335.355219968458, 486.147238845314, 623.244412005171,
748.505818444964, 860.86919935457, 983.642351192889, 1139.59065966632,
1231.14044698001, 350.834428083403, 510.783163477734, 661.443754597131,
809.775151175334, 937.8698594887, 1095.74073622628, 1275.45665833418,
1409.44183362004), .Dim = c(8L, 12L))
So cols 1,4,7 and 10 are the height of the bars. I want to do a grouped bar plot in ggplot2 so I do
library(ggplot2)
library(reshape2)
m[,c(1,4,7,10)]->m1
as.data.frame(m1)->m1
rownames(m1)<-c("t2","t3","t4","t5","t6","t7","t8","t9")
colnames(m1)<-c("a1","a2","a3","a4")
t(m1)->m1
melt(m1)->m1
ggplot(m1, aes(factor(Var2), value, fill = Var1)) +
geom_bar(stat="identity", position = "dodge") +
scale_fill_brewer(palette = "Set1")
Now I want to use cols 2,3;5,6;8,9 and 11,12 to draw error bars on the plot. So for the values in col 1, col 2 provides the lower CI and col 3 provides the upper CI (in absolute terms). This is then also for Cols 5 and 6 - that do that for col 4....
I found this here http://docs.ggplot2.org/0.9.3.1/geom_errorbar.html
but it only shows how to draw symmetric error bars - can somebody show me how to add error bars based on cols 2,3 .... to the grouped bar plot?
You example was not reproducible, so here's a slightly modified version of the example from ?geom_errorbar. Note that df contains variables upper and lower which are the upper and lower limits of the errorbars.
df <- data.frame(
trt = factor(c(1, 1, 2, 2)),
resp = c(1, 5, 3, 4),
group = factor(c(1, 2, 1, 2)),
upper = c(1.1, 5.3, 3.3, 4.2),
lower = c(0.8, 4.6, 2.4, 3.6)
)
dodge <- position_dodge(width=0.9)
ggplot(df, aes(trt, resp, fill = group)) +
geom_bar(position = dodge, stat = "identity") +
geom_errorbar(aes(ymin = lower, ymax = upper), position = dodge, width = 0.25)
Using your data.
# Values for the bar plots
m[,c(1,4,7,10)]->m1
as.data.frame(m1)->m1
rownames(m1)<-c("t2","t3","t4","t5","t6","t7","t8","t9")
colnames(m1)<-c("a1","a2","a3","a4")
t(m1)->m1
melt(m1)->m1
# Upper and lower limits for the error bars
error = m[,c(2,3,5,6,8,9,11,12)]
error = data.frame(error)
rownames(error)<-c("t2","t3","t4","t5","t6","t7","t8","t9")
colnames(error) = rep(c("a1","a2","a3","a4"), each = 2)
error = t(error)
error = melt(error)
error = cbind(error[seq(1, dim(error)[1], 2), ], error[seq(2, dim(error)[1], 2), 3])
names(error)[3:4] = c("lower", "upper")
# Combine the error bars and bar plot data frames
m1 = cbind(m1, error[, 3:4])
# Construct the plot
dodge <- position_dodge(width=0.9)
ggplot(m1, aes(factor(Var2), value, fill = Var1)) +
geom_bar(stat="identity", position = dodge) +
geom_errorbar(aes(ymin = lower, ymax = upper), position = dodge, width = 0.25) +
scale_fill_brewer(palette = "Set1")

Resources