Is there an existing function that creates confidence intervals
from a svyby
object for proportions (in my case a crosstab for a binary item in the survey
package). I often compare proportions across groups, and it would be very handy to have a function that can extract confidence intervals (with the survey function svyciprop
rather than confint
). The example below shows what I'd like to achieve.
Load data
library(survey)
library(weights)
data(api)
apiclus1$both<-dummify(apiclus1$both)[,1]#Create dummy variable
dclus1<-svydesign(id=~dnum, weights=~pw, data=apiclus1, fpc=~fpc)
Create a svyby object which compares proportion of variable "both" across stype
b<-svyby(~both, ~stype, dclus1, svymean)
confint(b)#This works, but svyciprop is best in other cases, especially when proportion is close to 0 or 1
svyciprop(b)#This requires that you specify each level and a design object
Would it be possible to create a function (e.g. byCI(b,method="likelihood")
which achieves the same as confint(b)
but using svyciprop
? It would basically have to go through each level of the svyby
object and create a confidence interval. My attempts have been unsuccessful up to now.
There may be another way around this, but I like using svyby()
as it's quick and intuitive.
More specifically, the confidence interval is calculated as the sample proportion ± z* times the standard deviation of the sample proportion, where z* is the critical value of z that has (1-C)/2 of the normal distribution to the right of the value, and the standard deviation is .
To calculate the confidence interval, we must find p′, q′. p′ = 0.842 is the sample proportion; this is the point estimate of the population proportion. Since the requested confidence level is CL = 0.95, then α = 1 – CL = 1 – 0.95 = 0.05 ( α 2 ) ( α 2 ) = 0.025.
One Proportion confidence intervals are used when you are dealing with a single proportion (ˆp). The critical value used will be z∗. Remember that: The sample proportion is denoted as ˆp.
svyby()
has a vartype=
argument to specify how you want the sampling uncertainty specified. Use vartype="ci"
to get confidence intervals, eg
svyby(~I(ell>0),~stype,design=dclus1, svyciprop,vartype="ci",method="beta")
It's easy to check that this gives the same as doing each level by hand, eg,
confint(svyciprop(~I(ell>0), design=subset(dclus1,stype=="E"),method="beta"))
interesting.. these two commands should not give the same result.. the first should probably throw an error or a warning:
svyby( ~both , ~stype , dclus1 , svyciprop , method = 'likelihood' )
svyby( ~both , ~stype , dclus1 , svymean )
you might want to alert Dr. Lumley to this issue -
the code near line 80 of surveyby.R
could probably be slightly modified to get svyciprop
working inside svyby
too..
but i may be overlooking something (and he may have noted it somewhere in the documentation),
so be sure to read everything carefully before contacting him about this
anyway, here's a temporary solution that might solve your problem
# create a svyby-like function specific for svyciprop
svyciby <-
function( formula , by , design , method = 'likelihood' , df = degf( design ) ){
# steal a bunch of code from the survey package's source
# stored in surveyby.R..
byfactors <- model.frame( by , model.frame( design ) , na.action = na.pass )
byfactor <- do.call( "interaction" , byfactors )
uniquelevels <- sort( unique( byfactor ) )
uniques <- match( uniquelevels , byfactor )
# note: this may not work for all types..
# i only tested it out on your example.
# run the svyciprop() function on every unique combo
all.cis <-
lapply(
uniques ,
function( i ){
svyciprop(
formula ,
design[ byfactor %in% byfactor[i] ] ,
method = method ,
df = df
)
}
)
# transpose the svyciprop confidence intervals
t.cis <- t( sapply( all.cis , attr , "ci" ) )
# tack on the names
dimnames( t.cis )[[1]] <- as.character( sort( unique( byfactor ) ) )
# return the results
t.cis
}
# test out the results
svyciby( ~both , ~stype , dclus1 , method = 'likelihood' )
# pretty close to your b, but not exact (as expected)
confint(b)
# and this one does match (as it should)
svyciby( ~both , ~stype , dclus1 , method = 'mean' , df = Inf )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With