I am analyzing the results of a survey on R. The questionnaire is a series of questions that participants answer using a Likert scale (https://en.wikipedia.org/wiki/Likert_scale).

I have obtained frequency tables for each question (i.e. what percentage of participants chose "strongly agree", what percentage chose "somewhat agree," etc.) and I am now interested in obtaining confidence intervals for those percentages.

Since I don't want to assume that my data is normally distributed, I was thinking of using bootstrapping to get the confidence intervals. However, I am not entirely sure how using bootstrapping works in this context. I am familiar with how to use bootstrapping when dealing with means, but not really when dealing with frequency tables such as these. Specifically, I am not sure how to go about coding the bootstrapping.

Thank you, Best,


2 Answers 2


There are different methods for calculating confidence intervals for proportions without using bootstrapping.

For a multinomial proportion, you might try the methods in the DescTools package.

### Adapted from http://rcompanion.org/handbook/H_02.html



SA = 10
A  = 9
N  = 20
D  = 5
SD = 1

observed = c(SA, A, N, D, SD)


### Methods: "sisonglaz", "cplus1", "goodman"

   ###              est     lwr.ci    upr.ci
   ### [1,] 0.22222222 0.08888889 0.3807871
   ### [2,] 0.20000000 0.06666667 0.3585648
   ### [3,] 0.44444444 0.31111111 0.6030093
   ### [4,] 0.11111111 0.00000000 0.2696759
   ### [5,] 0.02222222 0.00000000 0.1807871
  • $\begingroup$ Thank you! Can you let me know about the assumptions made by these methods? $\endgroup$
    – Max
    Commented Aug 17, 2017 at 13:25
  • $\begingroup$ I don't know if there are any assumptions. If you look at the function documentation, it lists the original references. ?MultinomCI or https://www.rdocumentation.org/packages/DescTools/versions/0.99.19/topics/MultinomCI. $\endgroup$ Commented Aug 17, 2017 at 13:28

Is this in the ballpark? I know my mock data are terrible. You should be able to calculate confidence intervals from the standard errors provided by the last line of code, and you can turn these results into a table again using dcast.

data<-data.frame(x=factor(c(10,30,50,30)), y=factor(c(2,4,6,3)))

bootstrap.rows<-replicate(1000, {
  sample(nrow(data), nrow(data), replace = TRUE)
}, simplify=FALSE)

bootstrap.samples<-lapply(bootstrap.rows, function(rows){
  data[rows, ]

tables<-lapply(bootstrap.samples, function(x){

tables<-do.call(rbind, tables)

aggregate(tables$value, by=list(tables$x, tables$y), FUN=mean)
aggregate(tables$value, by=list(tables$x, tables$y), FUN=sd)
  • $\begingroup$ I may be missing something, but I don't think the example provided is applicable for frequencies of levels of a categorical variable. Also, in the example, I don't understand what x and y are supposed to represent. $\endgroup$ Commented Nov 21, 2018 at 23:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.