Is there a concise way to remove the variable name in the legend of plots created by ggsurvplot?
Example:
library(survival)
library(survminer)
set.seed(123)
df=data.frame(gender=c(rep("male", 10), rep("female", 10)), value=c(rnorm(10,mean = 2), rnorm(10,mean = 3)))
fit = surv_fit(Surv(value) ~ gender, data = df)
p = ggsurvplot(fit, data = df, surv.median.line = "none")
What I want is to remove the word 'gender' from the legend as in the following plot. I can achieve this by manually setting the legend labels:
p = ggsurvplot(fit, data = df, surv.median.line = "none", legend.labs = c("male", "female"))
But is there a better way?
EDIT: I accidentally swapped male and female when I manually assigned the gender (2. plot), which shows how dangerous this method is.
Hack the strata with gsub.
names(fit$strata) <- gsub("gender=", "", names(fit$strata))
ggsurvplot(fit, data=df, surv.median.line="none")
To avoid the mistake of swapping the legend labels, use this option in the ggsurvplot function instead: legend.labs = levels(df$gender)
you can simply change the attribute of strata
attr(fit$strata,'names') <- c('female', 'male')
and then make the plot
p = ggsurvplot(fit, surv.median.line = "none")
Related
I want to only have labels every second number, but have the small ticks for every number in my graph. As you can see in the figure I added, the labels are every 2nd tick on the X-axis.
But I want to achieve the result that's on the Y-axis:
With ggplot, this is possible with ggh4x and if_elfse. But I can't find a way how to do this in ggsurvplot. This is my code, for the first picture. The code for the second picture is found here: Code 2
ggsurvplot(fit, data = d,
conf.int = F,
censor = F,
palette = c("green", "purple", "red"),
legend.labs = c("Reference water (pH 7.3)\n(N = 66)",
"Acidic al-poor (pH 5.8)\n(N = 66)",
"Acidic al-rich (pH 5.8)\n(N = 66)"),
legend.title = "Water quality",
xlab = "Days",
xlim = c(1,23),
break.time.by = 2
)
Thank you in advance for yor help.
As ggsurvplot returns a list containing the plot as a ggplot2 object you could achieve your desired result using ggh2x by overriding the x scale as in the example code by #tjebo from Adding minor tick marks to the x axis in ggplot2 (with no labels).
Making use of the default example from ?ggsruvplot:
library(survminer)
library(survival)
library(ggh4x)
fit<- survfit(Surv(time, status) ~ sex, data = lung)
p <- ggsurvplot(fit, data = lung, main = "Survival curve",
xlab = "Days",
xlim = c(1,23))
p$plot +
scale_x_continuous(minor_breaks = seq(0, 24, 1), breaks = seq(0, 24, 2), guide = "axis_minor") +
theme(ggh4x.axis.ticks.length.minor = rel(1))
#> Scale for 'x' is already present. Adding another scale for 'x', which will
#> replace the existing scale.
I would like to add line of text under the whole plot. However, it seems ggsurvplot handles plot and risk-table as two entities. I would like to have it like this: enter image description here
However, this is added in MS Word and the journal asks to have it embedded in the picture itself and I am unable to do that.
Thank you :-)
ggsurvplot(fit = fit, data = dat, pval = TRUE,
color = "black",
risk.table = T,
break.time.by = 12,
surv.scale = "percent",
linetype = c("solid","dotted", "dashed"),
legend.labs = c("Control group", "TMA R-ve", "TMA R+ve"),
censor.shape = 124,
legend.title = "",
title = "5-years death-censored graft survival",
xlab = "Months from transplantation",
ylab = "Survival (%)")
I suppose there may be multiple approaches to laying out the plot, table, and text caption. Here is one way I thought might be easier to work with.
The ggsurvplot object, if you include the risk table, will have two ggplot objects contained in it, one for the curve plot, and one for the table (the table itself is a plot).
You can just add to the table plot a caption, and this will appear below the table in the end. If you include hjust = 0 with plot.caption it will be left justified.
Here is an example:
library(survival)
library(survminer)
fit <- survfit(Surv(time, status) ~ sex, data = lung)
ggsurv <- ggsurvplot(fit, risk.table = TRUE)
ggsurv$table <- ggsurv$table +
theme(plot.caption = element_text(hjust = 0)) +
labs(caption = "Figure 1: 5-years death-censored graft survival")
ggsurv
I have the following code where I am building a survival curve with percentages instead of proportions. I am also breaking the survival time by tens. I would like to remove the percent symbols from the following plot as I would like to add that to the ylab title of the plot instead.
library(survival)
library(survminer)
data(lung)
fit <- survfit(Surv(time, status) ~sex, data = lung)
ggsurvplot(fit, risk.table = TRUE, axes.offset = FALSE,
break.y = 0.10,
surv.scale = c("percent"),
xlim = c(0, 1050))
One approach is to make the plot and then add a scale_y_continuous call which replaces the y-axis with whatever you want.
plot <- ggsurvplot(fit, risk.table = TRUE, axes.offset = FALSE,
xlim = c(0, 1050),
ylab = "Survival Probability (%)")
plot$plot <- plot$plot +
scale_y_continuous(breaks = seq(0,1,by=0.1), labels = seq(0,100,by=10))
plot
Why don't the package maintainers let you do this directly with +?
Consider this simple example:
tibble(time = c(1,2,3,4,5),
var1 = c(2,2,2,2,1),
var2 = c(2,1,1,4,5)) %>%
barchart(var1 + var2 ~ time,
data = .,
stack = TRUE,
horiz = FALSE,
par.settings = simpleTheme(col = c('red', 'blue'),
fill = c('red', 'blue'),
alpha = c(0.2)),
auto.key = TRUE)
Despite my attempts, I was not able to set the alpha for the bars. They are way too bright! Is there a way to do so?
Thanks!
Just use rgb() for your colors, the fourth argument is alpha:
library(tidyverse)
library(lattice)
tibble(
time = c(1,2,3,4,5),
var1 = c(2,2,2,2,1),
var2 = c(2,1,1,4,5)) %>%
barchart(var1 + var2 ~ time, data = .,
stack = TRUE, horiz = FALSE,
par.settings =
simpleTheme(
col = c(
rgb(1,0,0,0.2),
rgb(0,0,1,0.2)),
fill = c(
rgb(1,0,0,0.2),
rgb(0,0,1,0.2))),
auto.key = TRUE)
The panel.barchart function for some reason completely ignores the alpha= parameter. #rg255's suggestion of changing the color is certainly the easiest way to fix this problem. You could also re-rewrite the panel function to actually use the alpha= option. It's a pretty messy function but I put the re-write in this gist: https://gist.github.com/MrFlick/d705d63075dd1d0c804be8e5543b9e72. If you load that function then you could just add
panel="panel.barchart.alpha"
to the call to barchart(). Unfortunately this messed up the auto key just a bit (it draws points rather than rectangles. But you could hack that back to the default by doing something like this
pp <- barchart(..., panel="panel.barchart.alpha")
pp$legend$top$args$points <- FALSE
pp$legend$top$args$rectangles <- TRUE
When specifying colours to R, you can use the hexadecimal format. In this format, you can add two numbers to the end that will relate to the degree of translucency you require. I'm not saying this is the best way of doing it, but it's how I achieve translucency in my core R plots.
e.g.
# Black points
plot(rnorm(10), rnorm(10), pch = 20, col = "#000000")
# Black points with 50% translucency
plot(rnorm(10), rnorm(10), pch = 20, col = "#00000050")
I am using following commands to produce a scatterplot with jitter:
ddf = data.frame(NUMS = rnorm(500), GRP = sample(LETTERS[1:5],500,replace=T))
library(lattice)
stripplot(NUMS~GRP,data=ddf, jitter.data=T)
I want to add boxplots over these points (one for every group). I tried searching but I am not able to find code plotting all points (and not just outliers) and with jitter. How can I solve this. Thanks for your help.
Here's one way using base graphics.
boxplot(NUMS ~ GRP, data = ddf, lwd = 2, ylab = 'NUMS')
stripchart(NUMS ~ GRP, vertical = TRUE, data = ddf,
method = "jitter", add = TRUE, pch = 20, col = 'blue')
To do this in ggplot2, try:
ggplot(ddf, aes(x=GRP, y=NUMS)) +
geom_boxplot(outlier.shape=NA) + #avoid plotting outliers twice
geom_jitter(position=position_jitter(width=.1, height=0))
Obviously you can adjust the width and height arguments of position_jitter() to your liking (although I'd recommend height=0 since height jittering will make your plot inaccurate).
I've written an R function called spreadPoints() within a package basiclotteR. The package can be directly installed into your R library using the following code:
install.packages("devtools")
library("devtools")
install_github("JosephCrispell/basicPlotteR")
For the example provided, I used the following code to generate the example figure below.
ddf = data.frame(NUMS = rnorm(500), GRP = sample(LETTERS[1:5],500,replace=T))
boxplot(NUMS ~ GRP, data = ddf, lwd = 2, ylab = 'NUMS')
spreadPointsMultiple(data=ddf, responseColumn="NUMS", categoriesColumn="GRP",
col="blue", plotOutliers=TRUE)
It is a work in progress (the lack of formula as input is clunky!) but it provides a non-random method to spread points on the X axis that doubles as a violin like summary of the data. Take a look at the source code, if you're interested.
For a lattice solution:
library(lattice)
ddf = data.frame(NUMS = rnorm(500), GRP = sample(LETTERS[1:5], 500, replace = T))
bwplot(NUMS ~ GRP, ddf, panel = function(...) {
panel.bwplot(..., pch = "|")
panel.xyplot(..., jitter.x = TRUE)})
The default median dot symbol was changed to a line with pch = "|". Other properties of the box and whiskers can be adjusted with box.umbrella and box.rectangle through the trellis.par.set() function. The amount of jitter can be adjusted through a variable named factor where factor = 1.5 increases it by 50%.