funnel {ems} | R Documentation |
Produces a variety of funnel plots comparing health units or ICUs (intensive care units) making easy to identify those units which deviate from the group. There is a function that calculates all the values required and returns the values for all units and the funnel, and there is a function that calls graphical parameters from the former values. The options of funnels available are the funnel for rate, for ratio of rates, for proportions, for difference of proportions and for ratio of proportions.
The funnel for rates are usually plots of SMR (or SRU) at vertical axis and the number of admissions (if direct method) or the expected number of deaths (if inderect method) (or expected length of stay if SRU) in the horizontal axis. This allows the interpretation regarding the efficiency of preventing deaths (if SMR) or resourse use (if SRU), regardless of volume of addmissions (direct method) or expected number os deaths (indirect method).
The funnel for ratio of rates are usually plots of SMR (or SRU) ratios within the same units. These two SMRs are, for example, from the same unit in different time periods. Therefore, it expresses how to SMR changed over time. If the number of expected deaths are different in both periods, then the plot will return at the horizontal axis a parametrization of the geomentric mean of the expected number of deaths in both periods for each unit. If the number of expected deaths are identical in both periods, then the plot will return at the horizontal axis the arithmetic mean of the observed number of deaths in both periods for each unit.
The funnel for proportions plots on the vertical axis the percentage of observed deaths of the units and plots on the horizontal axis the number (volume) of admissions. The funnel for ratio of proportions and for difference of proportions are usually used to express the fraction of deaths of the same units in different time period. Therefore, they express how the fraction of deaths changed over time in each unit. If one picks the difference of proportions, the horizontal axis will be a parametrization of the arithmetic mean of the number of admissions in both periods. If one picks the ratio of proportions, the horizontal axis will be a parametrization of the geometric mean of the number of admissions in both periods.
funnel(unit, y, n, n1, n2, o, o1, o2, e, e1, e2, lambda1 = sum(o1)/sum(n1), lambda2 = sum(o2)/sum(n2), pi1 = sum(o1)/sum(n1), pi2 = sum(o2)/sum(n2), y.type = c("SMR", "SRU"), p = c(0.95, 0.998), theta, method = c("exact", "normal"), direct = FALSE, myunits = NULL, option = c("rate", "ratioRates", "prop", "diffProp", "ratioProp"), printUnits = TRUE, plot = TRUE, digits = 5, overdispersion = FALSE) ## S3 method for class 'funnel' print(x, ...) ## S3 method for class 'funnel' plot(x, ..., col = c("darkblue", "paleturquoise3", "gray26"), lwd = 2, lty = c(2, 6, 1), bty = "n", pch = 21, pt.col = "white", bg = "orange", pt.cex = 1.5, auto.legend = TRUE, text.cex = 0.7, text.pos = NULL, mypts.col = "darkblue", printUnits = x$printUnits, xlab = x$xlab, ylab = x$ylab, xlim = x$xlim, ylim = x$ylim)
unit |
A factor vector representing the unit names. |
y |
A numeric vector representing the "Standardized rate" for each unit, usually the SMR (Standardized Mortality Ratio), or possibly the SRU (Standardized Resource Use), accordind to |
n |
A numeric vector representing the case volume, or number of admissions, for each unit. |
n1, n2 |
If one picks |
o |
A numeric vector representing the observed death. Acceptable values are 0 (absence) or 1 (presence). |
o1, o2 |
If one picks |
e |
Used only when |
e1, e2 |
If one picks |
lambda1, lambda2 |
A value correponding to the rate which a death occurs in the instituitions at 1st and 2nd periods, respectively. Its assumed that O_i ~ Poi(lambda_i). Used when |
pi1, pi2 |
A value correponding to the probability wich a death occurs in the instituitions at 1st and 2nd periods, respectively. Its assumed that O_i ~ Bin(pi_i,n_i). Used when |
y.type |
A character vector representing the indicator type. It is used to name the vertical axis if |
p |
A confidence level numeric vector. It will return a confidence interval for all vector components. The default is 2 and 3 standard deviations ( |
theta |
Target value which specifies the desired expectation for institutions considered "in control". Used when |
method |
There are two kind of approximations, as discussed in |
direct |
Logical (default = |
myunits |
A character vector with the unit names which one would like to benchmark among all units. These units will be highlighted with dots of different collors in the plot. Default is |
option |
A character specifying the type of funnel plot one wants to produce. It can assume Suppose we have two measures for each institution: O1, N1 in a baseline period; and O2, N2 in a subsequent period; and we wish to assess the change in the underlying proportion form pi1 to pi2. Two different measures might be of interest: the difference in proportions or the ratio of proportions. Normal approximations are used throughout, and for low (especially zero) counts In case of |
printUnits |
Logical (default = |
plot |
Logical; If |
digits |
Integer indicating the number of decimals to be used in the output. |
overdispersion |
Logical (default = FALSE); If TRUE, introduces an multiplicative over-dispersion factor phi that will inflate the normal CI null variance. See details. |
x |
An object of class 'funnel'. |
... |
Further arguments passed to |
col |
A character vector representing the collors for the CI funnel lines. Must have same length of |
lwd |
A positive number specifying the lines width. It's the same for all lines in the plot. See |
lty |
A numeric vector representing the CI lines types. See |
bty |
A character string which representing the type of |
pch |
Either an integer or a single character specifying a symbol to be used as the default in plotting points. See |
pt.col |
A character specifying the points colors. |
bg |
A character specifying the color to be used for the points background when |
pt.cex |
A numerical value giving the amount by which plotting points should be magnified relative to the default. See |
auto.legend |
Logical; If |
text.cex |
A numerical value giving the amount by which plotting text should be magnified relative to the default. See |
text.pos |
A position specifier for numbers that correspond to the units in the plot. Values of 1, 2, 3 and 4, respectively indicate positions below, to the left of, above and to the right of the points. |
mypts.col |
A character representing the color used to benchmark the units specified in |
xlab, ylab |
A title for the x and y axis. See |
xlim, ylim |
Limits of horizontal and vertical axis. These limits are defined in the funnel plot and passed to |
If option = "rate"
, funnel
plots a standardized rate y versus its expected death or volume value for several units.
To choose the direct
argument, one should pay attention if one wants to use a Direct Standardized Rate or a Indirect Standardized Rate. If direct, we assume the rate is reported as a rate per (say) 1000 individuals, then it is treated as a proportion. If indirect, it is a cross-sectional data that leads to a standardized event ratio.
In many circumstances we can assume an exact or approximate normal distribution for the data. Using the method
argument, one could choose between "exact"
or "normal"
. For direct standardized rates, the exact distribuition is binomial and for indirect standardized rates, the exact distribuition is poisson. Assume rho is the precision parameter (volume, for direct rates; expected value, for indirect rates). The original report claims that, for rho > 100, the normal and exact curves almost coincide. So, one could perfectly use normal approximation if ones data parameter precision is greater than 100, in general.
The console warns if there are units with volume/expected value less than 100.
If overdispersion = TRUE
, the normal CI can be inflated by a overdispersion parameter phi. There are a test for overdispersion which inflate the funnel if it's necessary. An "Winsorezed" over-dispersion parameter is estimated and is used to inflate the funnel limits if it is significantly greater than 1. The parameter phi is returned as an funnel object.
phi = (1/total) * sum((y - theta) ^ 2 * rho)/g(theta)
var(y|theta,rho) = (phi * g(theta))/rho
If option = "ratioRate"
, funnel
can be used to compare units at two diferent periods. It plots a ratio of rates y versus a precision parameter rho.
Suppose we have two measures for each institution: O1; E1 in a baseline period and O2; E2 in a subsequent period, and we wish to assess the change in the underlying rate (SMR or SRU). We shall only consider the ratio of rates: exact methods based on a conditional argument are available if E1 = E2, and otherwise normal approximations are used, in which case for low (especially zero) counts the funnel
function adds 0.5 to all O's and E's.
Y = (O1/E1)/(O2/E2) and the target theta = lambda2/lambda1.
Theta is the target value which specifies the desired expectation for institutions considered "in control".
When E1 = E2, y is plotted versus the average observed count (rho).
When E1 is different of E2, i.e., its used normal approximation, it is convenient to work on a logarithmic scale so that log(theta) is a target for log(Y). And y is plotted versus the expectation per period (rho)
If overdispersion = TRUE
, the normal CI can be inflated by a overdispersion parameter phi. There are a test for overdispersion which inflate the funnel if it's necessary. An "Winsorezed" over-dispersion parameter is estimated and is used to inflate the funnel limits if it is significantly greater than 1. The parameter phi is returned as an funnel object.
If option = "prop"
, funnel
plots a proportion y versus its volume.
It is used for cross-sectional data. Suppose in each institution that O events are observed out of a sample size of N:
The indicator is the observed proportion y = O/N
Assume N
is the precision parameter (volume). For N
> 100 the normal and exact curves almost coincide. So, one could perfectly use normal approximation if ones data parameter precision is greater than 100, in general.
If overdispersion = TRUE
, the normal CI can be inflated by a overdispersion parameter phi. There are a test for overdispersion which inflate the funnel if it's necessary. An "Winsorezed" over-dispersion parameter is estimated and is used to inflate the funnel limits if it is significantly greater than 1. The parameter phi is returned as an funnel object.
phi = (1/total) * sum((y - theta) ^ 2 * N)/g(theta)
var(y|theta,N) = (phi * g(theta))/N
If option = "ratioProp"
or option = "diffProp"
, funnel
can be used to compare units at two diferent periods. It plots a ratio (or difference) of proportions y versus a precision parameter rho.
Suppose we have two measures for each institution: O1, N1 in a baseline period; and O2, N2 in a subsequent period; and we wish to assess the change in the underlying proportion form pi1 to pi2. Two different measures might be of interest: the difference in proportions or the ratio of proportions. Normal approximations are used throughout, and for low (especially zero) counts funnel
function add 0.5 to all r's and 1 to all n's in order to stabilize the estimates.
In case of option = "diffProp"
, the indicator is Y = (O2/N2 - O1/N1) and theta = pi2 - pi1. If option = "ratioProp"
, the indicator is Y = (O2/N2)/(O1/N1) and theta = pi2/pi1. Also, it is convenient to work on a logarithmic scale, so that log(theta) is a target for log(Y). Theta is the target value which specifies the desired expectation for institutions considered "in control".
For each cases, the precision parameter (plotted at x axis) can be interpreted as approximately the sample size per period.
If overdispersion = TRUE
, the normal CI can be inflated by a overdispersion parameter phi. There are a test for overdispersion which inflate the funnel if it's necessary. An "Winsorezed" over-dispersion parameter is estimated and is used to inflate the funnel limits if it is significantly greater than 1. The parameter phi is returned as an funnel object.
A table with unit names, y, observed (Obs), expected (Exp) and admissions (N) for each unit, and final columns show which units are out of control.
Spiegelhalter, David J. "Funnel plots for comparing institutional performance." Statistics in medicine 24.8 (2005): 1185-1202.
# Loading data data(icu) # Some edition icu$Saps3DeathProbabilityStandardEquation <- icu$Saps3DeathProbabilityStandardEquation / 100 icu <- icu[-which(icu$Unit == "F"),] icu <- droplevels(icu) # Getting the cross-sectional arguments to use in funnel x <- SMR.table(data = icu, group.var = "Unit", obs.var = "UnitDischargeName", pred.var = "Saps3DeathProbabilityStandardEquation") # Analysis of proportions f1 <- funnel(unit = x$Levels[-1], o = x[-1,]$Observed, theta = x$Observed[1] / x$N[1], n = x[-1,]$N, method = "exact", myunits = c("A"), option = "prop", plot = FALSE) f1 plot(f1, main = "Cross-sectional proportions") # To analyze rates (SMR) f2 <- funnel(unit = x$Levels[-1], y = x[-1,]$SMR, method = "exact", direct = TRUE, theta = x$SMR[1], e = x[-1,]$Expected, n = x[-1,]$N, o = x[-1,]$Observed, option = "rate", myunits = NULL, plot = FALSE) f2 plot(f2, main = "Cross-sectional rate (SMR)") # Creating a variable containing month information about each admission icu$month <- as.numeric(format(as.Date(icu$UnitAdmissionDateTime),"%m")) # First quarter dt1 <- icu[which(icu$month %in% c(1,2,3)),] # Second quarter dt2 <- icu[which(icu$month %in% c(4,5,6)),] # Getting the two period arguments to use in funnel z <- SMR.table(data = dt1, group.var = "Unit", obs.var = "UnitDischargeName", pred.var = "Saps3DeathProbabilityStandardEquation") w <- SMR.table(data = dt2, group.var = "Unit", obs.var = "UnitDischargeName", pred.var = "Saps3DeathProbabilityStandardEquation") # To analyze periods using ratio rates with e1 = e1 f3 <- funnel(unit = z$Levels[-1], n1 = z$N[-1], o1 = z$Observed[-1], e1 = z$Expected[-1], n2 = w$N[-1], o2 = w$Observed[-1], e2 = z$Expected[-1], myunits = c("A","B"), option = "ratioRates", plot = FALSE) f3 plot(f3, main = "Ratio of SMRs of periods with same expectation of death") # To analyze periods using ratio rates with e1 =! e1 f4 <- funnel(unit <- z$Levels[-1], n1 = z$N[-1], o1 = z$Observed[-1], e1 = z$Expected[-1], n2 = w$N[-1], o2 = w$Observed[-1], e2 = w$Expected[-1], option = "ratioRates", plot = FALSE) f4 plot(f4, main = "Ratio of SMRs of periods with different expectation of death", ylim = c(-1.5,1.5), xlim = c(0,200)) # To analyze periods by difference in proportions f5 <- funnel(unit <- z$Levels[-1], n1 = z$N[-1], o1 = z$Observed[-1], n2 = w$N[-1], o2 = w$Observed[-1], option = "diffProp", plot = FALSE) f5 plot(f5, main = "Difference in proportions of death for two periods") # To analyze periods by ratio of proportions f6 <- funnel(unit <- z$Levels[-1], n1 = z$N[-1], o1 = z$Observed[-1], n2 = w$N[-1], o2 = w$Observed[-1], option = "ratioProp", plot = FALSE) f6 plot(f6, main = "Ratio of proportions of death for two periods") rm(icu, x, z, w, dt1, dt2, unit, f1, f2, f3, f4, f5, f6)