Como título, necesito dibujar algo así:
¿Se puede utilizar ggplot, u otros paquetes si ggplot no es capaz, para dibujar algo así?
Como título, necesito dibujar algo así:
¿Se puede utilizar ggplot, u otros paquetes si ggplot no es capaz, para dibujar algo así?
Si busca este tipo (meta-análisis) de gráfico de embudo entonces lo siguiente podría ser un punto de partida:
library(ggplot2)
set.seed(1)
p <- runif(100)
number <- sample(1:1000, 100, replace = TRUE)
p.se <- sqrt((p*(1-p)) / (number))
df <- data.frame(p, number, p.se)
## common effect (fixed effect model)
p.fem <- weighted.mean(p, 1/p.se^2)
## lower and upper limits for 95% and 99.9% CI, based on FEM estimator
number.seq <- seq(0.001, max(number), 0.1)
number.ll95 <- p.fem - 1.96 * sqrt((p.fem*(1-p.fem)) / (number.seq))
number.ul95 <- p.fem + 1.96 * sqrt((p.fem*(1-p.fem)) / (number.seq))
number.ll999 <- p.fem - 3.29 * sqrt((p.fem*(1-p.fem)) / (number.seq))
number.ul999 <- p.fem + 3.29 * sqrt((p.fem*(1-p.fem)) / (number.seq))
dfCI <- data.frame(number.ll95, number.ul95, number.ll999, number.ul999, number.seq, p.fem)
## draw plot
fp <- ggplot(aes(x = number, y = p), data = df) +
geom_point(shape = 1) +
geom_line(aes(x = number.seq, y = number.ll95), data = dfCI) +
geom_line(aes(x = number.seq, y = number.ul95), data = dfCI) +
geom_line(aes(x = number.seq, y = number.ll999), linetype = "dashed", data = dfCI) +
geom_line(aes(x = number.seq, y = number.ul999), linetype = "dashed", data = dfCI) +
geom_hline(aes(yintercept = p.fem), data = dfCI) +
scale_y_continuous(limits = c(0,1.1)) +
xlab("number") + ylab("p") + theme_bw()
fp
La presencia del linetype=2
dentro del argumento aes()
paréntesis - trazar las líneas del 99% - da un error "la variable continua no puede ser asignada al tipo de línea" con el actual ggplot2 (0.9.3.1). Modificación de geom_line(aes(x = number.seq, y = number.ll999, linetype = 2), data = dfCI)
a geom_line(aes(x = number.seq, y = number.ll999), linetype = 2, data = dfCI)
funciona para mí. Siéntase libre de modificar la respuesta original y perder esto.
Aunque se puede mejorar, he aquí un pequeño intento con datos simulados (heteroscedásticos):
library(ggplot2)
set.seed(101)
x <- runif(100, min=1, max=10)
y <- rnorm(length(x), mean=5, sd=0.1*x)
df <- data.frame(x=x*70, y=y)
m <- lm(y ~ x, data=df)
fit95 <- predict(m, interval="conf", level=.95)
fit99 <- predict(m, interval="conf", level=.999)
df <- cbind.data.frame(df,
lwr95=fit95[,"lwr"], upr95=fit95[,"upr"],
lwr99=fit99[,"lwr"], upr99=fit99[,"upr"])
p <- ggplot(df, aes(x, y))
p + geom_point() +
geom_smooth(method="lm", colour="black", lwd=1.1, se=FALSE) +
geom_line(aes(y = upr95), color="black", linetype=2) +
geom_line(aes(y = lwr95), color="black", linetype=2) +
geom_line(aes(y = upr99), color="red", linetype=3) +
geom_line(aes(y = lwr99), color="red", linetype=3) +
annotate("text", 100, 6.5, label="95% limit", colour="black",
size=3, hjust=0) +
annotate("text", 100, 6.4, label="99.9% limit", colour="red",
size=3, hjust=0) +
labs(x="No. admissions...", y="Percentage of patients...") +
theme_bw()
El código de Bernd Weiss es muy útil. He hecho algunas modificaciones a continuación, para cambiar/añadir algunas características:
geom_segment
en lugar de geom_line
para la línea que delimita la media del meta-análisis, de modo que tenga la misma altura que las líneas que delimitan las regiones de confianza del 95% y del 99%.Mi código utiliza una media meta-analítica de 0,0892 (se = 0,0035) como ejemplo, pero usted puede sustituir sus propios valores.
estimate = 0.0892
se = 0.0035
#Store a vector of values that spans the range from 0
#to the max value of impression (standard error) in your dataset.
#Make the increment (the final value) small enough (I choose 0.001)
#to ensure your whole range of data is captured
se.seq=seq(0, max(dat$corr_zi_se), 0.001)
#Compute vectors of the lower-limit and upper limit values for
#the 95% CI region
ll95 = estimate-(1.96*se.seq)
ul95 = estimate+(1.96*se.seq)
#Do this for a 99% CI region too
ll99 = estimate-(3.29*se.seq)
ul99 = estimate+(3.29*se.seq)
#And finally, calculate the confidence interval for your meta-analytic estimate
meanll95 = estimate-(1.96*se)
meanul95 = estimate+(1.96*se)
#Put all calculated values into one data frame
#You might get a warning about '...row names were found from a short variable...'
#You can ignore it.
dfCI = data.frame(ll95, ul95, ll99, ul99, se.seq, estimate, meanll95, meanul95)
#Draw Plot
fp = ggplot(aes(x = se, y = Zr), data = dat) +
geom_point(shape = 1) +
xlab('Standard Error') + ylab('Zr')+
geom_line(aes(x = se.seq, y = ll95), linetype = 'dotted', data = dfCI) +
geom_line(aes(x = se.seq, y = ul95), linetype = 'dotted', data = dfCI) +
geom_line(aes(x = se.seq, y = ll99), linetype = 'dashed', data = dfCI) +
geom_line(aes(x = se.seq, y = ul99), linetype = 'dashed', data = dfCI) +
geom_segment(aes(x = min(se.seq), y = meanll95, xend = max(se.seq), yend = meanll95), linetype='dotted', data=dfCI) +
geom_segment(aes(x = min(se.seq), y = meanul95, xend = max(se.seq), yend = meanul95), linetype='dotted', data=dfCI) +
scale_x_reverse()+
scale_y_continuous(breaks=seq(-1.25,2,0.25))+
coord_flip()+
theme_bw()
fp
Ver también el paquete cran berryFunctions, que tiene un funnelPlot para proporciones sin usar ggplot2, por si alguien lo necesita en gráficos base. http://cran.r-project.org/web/packages/berryFunctions/index.html
También existe el paquete extfunnel, que no he mirado.
I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.
2 votos
Tengo algunas ideas sobre cómo hacer y aplicar esto, pero agradecería tener algunos datos con los que jugar. ¿Alguna idea al respecto?
1 votos
Sí, ggplot puede dibujar fácilmente un gráfico formado por puntos y líneas ;) geom_smooth te llevará al 95% del camino - si quieres más consejos tendrás que proporcionar más detalles.
2 votos
Esto no es un gráfico de embudo. En su lugar, las líneas se construyen evidentemente a partir de estimaciones de errores estándar basadas en el número de admisiones. Parecen tener la intención de encerrar un proporción de datos, lo que les haría límites de tolerancia. Probablemente sean de la forma y = línea de base + constante / Sqrt(# admisiones * f(línea de base)). Se podría modificar el código de las respuestas existentes para graficar las líneas, pero es probable que tenga que proporcionar su propia fórmula para calcularlas: los ejemplos que he visto trazan intervalos de confianza para el línea de montaje en sí misma . Por eso se ven tan diferentes.
0 votos
@whuber (+1) Es un punto muy bueno, de hecho. Espero que esto pueda proporcionar un buen punto de partida de todos modos (incluso si mi código R no es tan optimizado).
0 votos
Ggplot sigue proporcionando
stat_quantile()
para poner cuantiles condicionales en un gráfico de dispersión. A continuación, puede controlar la forma funcional de la regresión cuantílica con el parámetro de la fórmula. Yo sugeriría cosas como formula=y~ns(x,4)
para conseguir un ajuste suave de las estrías.