6

I have demographic data and for some of the variables I want to show Mean (95% CI) So far:

> label (demog$Site) = "Site"
> label (demog$Sex) = "Sex"
> label (demog$Age) = "Age (years)"
> label (demog$Temperature) = "Temperature (Celcius)"
> label (demog$MOI) = "MOI"
> 
> table1(~Sex + Age + Temperature + MOI | Site, data = demog)

This gives me all of my varaibles stratified by the sampling site, which is what I want. But it reports the Mean (SD), Median [Min, Max], and Missing for each continuous variable (everything but "Sex"), which I don't want.

To change what was shown, I tried mimicking this: https://benjaminrich.github.io/table1/vignettes/table1-examples.html

I made:

> my.render.cont = function(x) {with(stats.apply.rounding(stats.default(x), digits=2), c("", "Mean (95% CI)"=sprintf("%s (± %s)", MEAN, (MEAN + SD*1.96), (MEAN - SD*1.96))))}
> my.render.cat = function(x) {c("", sapply(stats.default(x), function(y) with(y, sprintf("%d (%0.0f %%)", FREQ, PCT))))}
> strata = c(list(Total=demog), split(demog, demog$Site))

But when I tried to actually show the table

> table1(strata, labels, render.continuous=my.render.cont, render.categorical=my.render.cat)
Error: object of type 'closure' is not subsettable

I don't necessarily care about showing the 95% CIs this specific way, I just want to show them. If anyone has a fix to this error, great. If anyone has an entirely different way to show Mean (95% CI) in this table, also great

Phil
  • 7,287
  • 3
  • 36
  • 66
ajmoo
  • 61
  • 2

1 Answers1

0

Rather than using MEAN and SD, access the statistics using stats.default(x)$MEAN and stats.default(x)$SD. Minimal worked example for a confidence interval for the mean, using the melanoma data from the link you shared.

library(boot)
library(stats)

meldf <- melanoma
meldf$status.f <- factor(meldf$status)
meldf$ulcer.f <- factor(meldf$ulcer)

labels <- list(
    variables=list(status.f='Status',
                   ulcer.f='Ulcer Y/N',
                   age='Age',
                   thickness='Thickness'
                   ))

strata <- split(meldf, meldf$sex)

my.render.cont = function(x, name, ...) {
    if (name=='thickness') {
         c("", "95% CI"=sprintf("%s &plusmn; %s",
                                       round(stats.default(x)$MEAN-qt(0.975,stats.default(x)$N-1)*stats.default(x)$SD/sqrt(stats.default(x)$N),6),
                                       round(stats.default(x)$MEAN+qt(0.975,stats.default(x)$N-1)*stats.default(x)$SD/sqrt(stats.default(x)$N),6)))
    }
    else {
        render.default(x, name, ...)
    }
}
    
tbl2 <- table1(strata,
              labels,
              render.continuous=c(.="Median", .="Q1-Q3"), # in case you have other stats you want to display differently
              render=my.render.cont)
tbl2

You can check the confidence intervals using:

t.test(meldf[meldf$sex==0,]$thickness)$conf.int
t.test(meldf[meldf$sex==1,]$thickness)$conf.int
nolankev
  • 1
  • 1