基于 Predict 对象(rms 包)更改 ggplot 的轴范围
Change axis ranges for a ggplot based on a Predict object (rms package)
我正在使用 rms 包执行 Cox 回归,年龄为 4 节的受限三次样条,请参阅下面来自 rms 包文档的可重现代码。
我的问题是:如何更改 ggplot 输出的 y 轴间隔?我尝试添加 scale_y_continuous(limits = c(0,20)) 但它并没有改变轴
library(ggplot)
library(rms)
# NOT RUN {
# Simulate data from a population model in which the log hazard
# function is linear in age and there is no age x sex interaction
n <- 1000
set.seed(731)
age <- 50 + 12*rnorm(n)
label(age) <- "Age"
sex <- factor(sample(c('Male','Female'), n,
rep=TRUE, prob=c(.6, .4)))
cens <- 15*runif(n)
h <- .02*exp(.04*(age-50)+.8*(sex=='Female'))
dt <- -log(runif(n))/h
label(dt) <- 'Follow-up Time'
e <- ifelse(dt <= cens,1,0)
dt <- pmin(dt, cens)
units(dt) <- "Year"
dd <- datadist(age, sex)
options(datadist='dd')
S <- Surv(dt,e)
f <- cph(S ~ rcs(age,4) + sex, x=TRUE, y=TRUE)
cox.zph(f, "rank") # tests of PH
anova(f)
ggplot(Predict(f, age, sex, fun=exp)) + # plot age effect, 2 curves for 2 sexes
scale_y_continuous(limits = c(0,20))
不同寻常的是,rms
的Predict
class有自己的ggplot
的S3方法,它会自动添加位置比例、坐标和geom图层。这使得绘制 Predict
对象更容易,但限制了可扩展性。特别是,它已经通过 CoordCartesian
设置了 y 限制,over-rides 您添加的任何 y 轴比例。
最简单的方法是添加一个新的 coord_cartesian
,它将 over-ride 现有的 Coord
对象(尽管也会生成一条消息)。
ggplot(Predict(f, age, sex, fun=exp)) + # plot age effect, 2 curves for 2 sexes
coord_cartesian(ylim = c(0, 20))
#> Coordinate system already present. Adding new coordinate system,
#> which will replace the existing one.
另一种方法是存储绘图并更改其坐标限制,这不会生成消息但有点“hacky”
p <- ggplot(Predict(f, age, sex, fun=exp))
p$coordinates$limits$y <- c(0, 20)
p
您还可以在上面的代码中将 y 轴限制更改为 NULL
,这将允许您使用 scale_y_continuous
来设置轴限制。
虽然有点费力,但您始终可以通过先将对象转换为 data.frame
来从第一原理创建情节。这种方式的好处是您可以完全控制要添加的内容。
age_data <- as.data.frame(Predict(f, age, sex, fun = exp))
ggplot(age_data, aes(x = age, y = yhat, colour = sex)) +
geom_line() +
geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.2) +
scale_y_continuous(limits = c(0, 20))
@Allans 方法对于您的特定要求来说要简单得多!
我正在使用 rms 包执行 Cox 回归,年龄为 4 节的受限三次样条,请参阅下面来自 rms 包文档的可重现代码。 我的问题是:如何更改 ggplot 输出的 y 轴间隔?我尝试添加 scale_y_continuous(limits = c(0,20)) 但它并没有改变轴
library(ggplot)
library(rms)
# NOT RUN {
# Simulate data from a population model in which the log hazard
# function is linear in age and there is no age x sex interaction
n <- 1000
set.seed(731)
age <- 50 + 12*rnorm(n)
label(age) <- "Age"
sex <- factor(sample(c('Male','Female'), n,
rep=TRUE, prob=c(.6, .4)))
cens <- 15*runif(n)
h <- .02*exp(.04*(age-50)+.8*(sex=='Female'))
dt <- -log(runif(n))/h
label(dt) <- 'Follow-up Time'
e <- ifelse(dt <= cens,1,0)
dt <- pmin(dt, cens)
units(dt) <- "Year"
dd <- datadist(age, sex)
options(datadist='dd')
S <- Surv(dt,e)
f <- cph(S ~ rcs(age,4) + sex, x=TRUE, y=TRUE)
cox.zph(f, "rank") # tests of PH
anova(f)
ggplot(Predict(f, age, sex, fun=exp)) + # plot age effect, 2 curves for 2 sexes
scale_y_continuous(limits = c(0,20))
不同寻常的是,rms
的Predict
class有自己的ggplot
的S3方法,它会自动添加位置比例、坐标和geom图层。这使得绘制 Predict
对象更容易,但限制了可扩展性。特别是,它已经通过 CoordCartesian
设置了 y 限制,over-rides 您添加的任何 y 轴比例。
最简单的方法是添加一个新的 coord_cartesian
,它将 over-ride 现有的 Coord
对象(尽管也会生成一条消息)。
ggplot(Predict(f, age, sex, fun=exp)) + # plot age effect, 2 curves for 2 sexes
coord_cartesian(ylim = c(0, 20))
#> Coordinate system already present. Adding new coordinate system,
#> which will replace the existing one.
另一种方法是存储绘图并更改其坐标限制,这不会生成消息但有点“hacky”
p <- ggplot(Predict(f, age, sex, fun=exp))
p$coordinates$limits$y <- c(0, 20)
p
您还可以在上面的代码中将 y 轴限制更改为 NULL
,这将允许您使用 scale_y_continuous
来设置轴限制。
虽然有点费力,但您始终可以通过先将对象转换为 data.frame
来从第一原理创建情节。这种方式的好处是您可以完全控制要添加的内容。
age_data <- as.data.frame(Predict(f, age, sex, fun = exp))
ggplot(age_data, aes(x = age, y = yhat, colour = sex)) +
geom_line() +
geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.2) +
scale_y_continuous(limits = c(0, 20))
@Allans 方法对于您的特定要求来说要简单得多!