2
$\begingroup$

I have similar recurring use case at work whereby we are wanting to understand attributes/features of a datasets such as 'how many customers talk about this', 'how many customers do that' and generally the only knowns that I think are relevant are the populatation sizes.

In this current example what we have is a dataset that containts 9636 survey responses and another dataset that has been previously analysed of customer feedback that has been categorised. The categorised dataset is different to the current survey dataset but we are running on the assumption that the categories will be similar. What we are seeking to understand is the proportions of the 9636 surveys that can be categorised into 1 of the 12 categories from the second dataset.

Is there a general sample size calculation method for this type of use case and if so can someone plese provide detail on what the method for calculating the sample size for this use case? I intend on calculating this in r so if anyone has any r code snippets that would help here I would also greatly appreciate it.

Thank you in advance! This is a recurring requirement at work (calculating sample sizes that will give our stakeholders confidence that the results are relevant to the population in question). As a side note, my stakeholders often ask for 'what sample size will be statistically significant' - could anyone additionally provide any feedback on technically whether this is the right question to be asking for the use case/s I have outlined in this post.

Thanks again. I appreciate any help or insight.

EDIT 1 - adding details to clarify Dataset 1 is a list of reasons why customers might need to speak to our contact centre and there is 1 category with 12 levels. Dataset 2 is the survey responses and we will classify the reason for low scores using the same 12 levels from dataset 1 (as there is an underlying assumption that the reasons for being unhappy about the product or service and thus result in a call to our contact centre, will be the same reasons why customers will state in a survey they are unhappy with the product or service.

EDIT 2 Dataset 2 is a set of survey responses that we need to categorise into (hopefully, if our assumptions hold up) 1 of 12 categories. Dataset 1 is where those 12 categories were initially defined but this was not a survey dataset - it was a dataset of transcripts from contact centre calls (and analysed them in order to categorise the 'root cause of their issue') so the customers in dataset 2 are unlikely for the most part to be the same customers in dataset 1.

EDIT 3 Essentially what we are trying to answer/test is 'are the reasons for customer calls the same reasons why customers are detractors in an NPS survey'. I am not sure what test I would run to test for this but my initial question is at the top of this process which is 'how do we calculate the size of the sample we need to analyse in dataset 2 in order to give confidence that whatever we find is likely to be representative of the whole population (of survey respondants).

$\endgroup$
6
  • $\begingroup$ Hello Jo and welcome on CrossValidated! It is a bit unclear to me what you mean when you ask if the responses to your first survey "can be categorised into 1 of the 12 categories from the second dataset". Are you trying to compare if the distribution of answers among the 12 categories in the second sample is similar to the distribution of answers in the first sample? Another thing: are you talking about one category with 12 different levels (i.e. one answer can't be in more than one level), or 12 different variables (i.e. one answer can be classified simultaneously in more than one category)? $\endgroup$
    – J-J-J
    Commented May 28, 2023 at 9:09
  • 1
    $\begingroup$ Thank you for your response and clarifying questions. Let me try and clarify: Dataset 1 is a list of reasons why customers might need to speak to our contact centre and there is 1 category with 12 levels. Dataset 2 is the survey responses and we will classify the reason for low scores using the same 12 levels from dataset 1 (as there is an underlying assumption that the reasons for being unhappy about the product or service and thus result in a call to our contact centre, will be the same reasons why customers will state in a survey they are unhappy with the product or service. Thanks! $\endgroup$
    – K-J
    Commented May 28, 2023 at 11:38
  • $\begingroup$ Do you have an idea of the statistical test you want to use to compare the two datasets? If not, did the people in the second dataset also answered the first survey? If they did, are you able to track how each person specifically answered the two surveys? (i.e. if you're able to say if the category for a given person is different in dataset 1 and dataset 2). .The answer to these questions may have an impact on the statistical test to choose for comparing the two distributions, and therefore on how to calculate a relevant sample size. $\endgroup$
    – J-J-J
    Commented May 29, 2023 at 7:34
  • $\begingroup$ (Note that if you want, you can edit your original post to add all these information, rather than answering in the comment section). $\endgroup$
    – J-J-J
    Commented May 29, 2023 at 7:35
  • 1
    $\begingroup$ Thanks @J-J-J .. I have updated the OP with answers to your questions (thanks for the advice to update the OP rather than reply with answers in a comment :) ) $\endgroup$
    – K-J
    Commented May 29, 2023 at 8:15

1 Answer 1

3
$\begingroup$

To restate things and make sure there's no misunderstanding:

You have a "reference dataset" (i.e. your "previously analyzed dataset") with a categorical distribution among 12 levels, maybe looking like that (in R):

#note that this vector is sorted by decreasing order, the maximum proportion being 30%, and the smallest 1%
reference_distribution = c(0.30, 0.15, 0.12, 0.08, 0.08, 0.07, 0.06, 0.04, 0.03, 0.03, 0.03, 0.01) 
#But let's make sure this is sorted in decreasing order anyway - this will be important for coding purposes later.
reference_distribution = sort(reference_distribution, decreasing=TRUE) 

You plan to collect data from another source (or have already collected the data), and want to compare this new sample to the reference distribution above, to see if their discrepancies (that will inevitably happen) are concerning. You want to make sure that the size of your new sample is large enough to get a reliable result relative to these differences, or if you need to collect additional data.

In short: when you need to calculate a sample size, you have to, in this order:

  1. determine the statistical test adequate for your purpose;
  2. determine the minimal effect size you're interested in;
  3. calculate the required sample size.

1- Choosing an appropriate test

An appropriate statistical test here to compare your new sample to the reference distribution is almost certainly a chi-square goodness-of-fit test, which is meant to compare categorical distributions. In short, the chi-squared test answers the question: "If the sample really comes from the reference distribution, how likely is it for this sample to look like this?".

Had your data being paired (that is, the same customers answered the first and second survey, and you wanted to check if these customers changed their mind between the first and second survey), a more appropriate test would have been the Stuart-Maxwell test. It would have implied a different (and probably more complicated) procedure for calculating the required sample size. Here, we'll stick to the chi-square goodness-of-fit test, as it seems more appropriate for your data.

You'll find a short documentation for the chi-squared goodness-of-fit test in R on this page. This is an extremely common statistical test, and many free online resources (including this very website) are available on how to interpret correctly the result of this test. So I don't think it is necessary to explain it in detail in this answer.

If the chi-squared test shows that something is going on (i.e. that there's an overall difference between your sample and the reference distribution), you might also want to examine the residuals to see which levels are driving this overall difference. You'll find a technical but useful discussion on residuals in this article by D. Sharpe (2015).

But this short presentation of the chi-squared test was just an aside, and using this test will come after you collected your data. The important step here was simply to identify in advance the test to use after the data has been collected. It is important to identify the correct test beforehand, because it affects the way to calculate the required sample size.

2- Defining a minimal effect size you care about

The ability of the chi-square goodness-of-fit test to detect a difference if it exists is called its power. As the sample size increases, power increases. A consequence of that is if the sample size is too small, you might miss a difference you're interested in, and this is probably what your stakeholders are worried about. But on the other hand, if the sample size is too large, the test may detect differences that actually do not matter to you, so it might make you worry when there's no reason to (a note on that at the end of this answer).

So you want to run an a priori power analysis for the chi-square goodness-of-fit test, which will give you an appropriate sample size to detect the minimal effect you're interested in.

In R, the pwr library may help you conducting this kind of analysis for the chi-square test. Other statistical software or languages generally also offer this kind of feature, e.g. GPower which is specialized in power analysis, or the statsmodels library in Python.

To conduct a power analysis, you have to define beforehand the magnitude of the difference you want to be able to detect between the sample and its hypothesized distribution.

For that, you can ask yourself what kind of difference it would be problematic or not to miss.

To take an example, let's say you're interested in detecting a deviation/difference of at least $\pm8\%$ in at least one level/cell (because for whatever reasons specific to your business, you know that deviations smaller than 8% would not really matter).

diff = 0.08 #this is the difference we want to be able to detect in at least one cell, to let's enter that in R.

"A deviation of 8% in at least one cell" is a very specific criteria, and in the following 3 or 4 paragraphs, I'm going to detail quite a bit how to deal with it. But you don't have to use this kind of criteria or to follow exactly the specific workflow I'm going to suggest. It's just an example to give you an idea of how to think about it. You may have better ideas of criteria relevant to your situation. The main idea here is that smaller the difference you care about, the bigger the sample size will have to be - so you have to think carefully about what kind of difference/deviation is of interest to you.

Returning to our example, one of the "worst case scenarios" would be if this difference of $\pm8\%$ happened in the largest proportion cell of the reference distribution (in our example above, 0.3), because differences in largest cells are more difficult to detect for the chi-square goodness-of-fit test. Here, it would mean a proportion of 0.22 for this level in the new sample (it could have been 0.38 too, but let's take the example of 0.22).

An "even worst case scenario" is if the 8% you'd have to add elsewhere are added to each remaining level in a proportional way (it makes the deviation even harder to detect).

Let's create a hypothetical sample to simulate this "worst case scenario":

new_sample = c( reference_distribution[1] - diff) #we substract 8% from 30%. For the moment, this vector is just c(0.22)
#let's add 8% proportionally to the remaining levels
remaining_prop = reference_distribution[2:length(reference_distribution)] #we retrieve a vector containing only the remaining levels
remaining_prop = remaining_prop + (remaining_prop/sum(remaining_prop)* diff) #we add the 8% proportionally to each remaining level
new_sample= c(new_sample, remaining_prop )
new_sample
 [1] 0.22000000 0.16714286 0.13371429 0.08914286 0.08914286 0.07800000 0.06685714 0.04457143 0.03342857 0.03342857 0.03342857 0.01114286

So we now have a reference distribution and a hypothetical "worst-case scenario" sample, that look like that if we compare their distributions side by side:

level Reference distribution Hypothetical "worst-case scenario" sample
A 0.30 0.22
B 0.15 0.16714286
C 0.12 0.13371429
D 0.08 0.08914286
E 0.08 0.08914286
F 0.07 0.07800000
G 0.06 0.06685714
H 0.04 0.04457143
I 0.03 0.03342857
J 0.03 0.03342857
K 0.03 0.03342857
L 0.01 0.01114286

From this hypothetical "worst-case" sample and from the reference distribution, we are now able to calculate an effect size, essentially measuring the deviation of the sample from the reference distribution. We will then plug this effect size into the appropriate pwr method to get the required sample size.

The appropriate effect size for a chi-square goodness-of-fit test is called Cohen's $\omega$ (this is the Greek letter omega, but some people simply call it "Cohen's w").

Here's how to calculate the effect size Cohen's $\omega$ with the pwr library, using the reference distribution and the hypothetical sample we created before:

library(pwr)  
effect_size_w = ES.w1(reference_distribution, new_sample)
effect_size_w 
>>>0.1745743

Here, $\omega = 0.1745743$. (In case you want to calculate $\omega$ manually, you can find the formula on the Wikipedia article about effect sizes).

Higher $\omega$ is, more different the two distributions are, and lower it is, more similar they are. Here, 0.1745743 is the smallest possible $\omega$ we get given a criteria of "a difference of at least 8% in at least one cell". If we want to err on the side of caution, we can round it to 0.17:

effect_size_w = round(effect_size_w , 2)

Now that we have the smallest possible effect size we care about, we're almost ready to calculate the sample size required to detect an effect size of at least this magnitude.

3- Calculating the required sample size

We still have to define an alpha level, and the power of the test. Choosing 0.05 for alpha is very common, but it entirely depends on your use case and you may want to choose a smaller level (see this discussion). A power of 0.8 is also very common to choose (but here again, you may want a higher level).

So we just have to plug in pwr the effect size we calculated earlier ($\omega=0.17$), the alpha level, the power, and the degrees of freedom (number of levels minus one). With an alpha level of 0.01 and a power of 0.9, here is what we'd get:

 pwr.chisq.test(w=effect_size_w, df=(12-1), sig.level=0.01, power=0.9)

   Chi squared power calculation 

              w = 0.17
              N = 961.857
             df = 11
      sig.level = 0.01
          power = 0.9

NOTE: N is the number of observations

So this a required sample size (N) of 962 for this specific example.

You may want to adjust this number upward to account for possible problems like non-responses, duplicate answers, and other shenanigans, depending on your knowledge of the people you're surveying.

4- After collecting the data

We collected our data, and maybe we have a sample looking like that:

real_sample = c(209,  98,  79,  66, 115,  87,  58,  60,  77,  65,  22,  26)
#in proportions, this is c(0.21725572, 0.10187110, 0.08212058, 0.06860707, 0.11954262, 0.09043659, 0.06029106, 0.06237006, 0.08004158, 0.06756757, 0.02286902, 0.02702703)

If we compare our collected sample to the reference distribution, we have something like that:

level Reference distribution real collected sample
A 0.30 0.21725572
B 0.15 0.10187110
C 0.12 0.08212058
D 0.08 0.06860707
E 0.08 0.11954262
F 0.07 0.09043659
G 0.06 0.06029106
H 0.04 0.06237006
I 0.03 0.08004158
J 0.03 0.06756757
K 0.03 0.02286902
L 0.01 0.02702703

We can run the chi-square test to check how likely it is that this sample comes from the reference distribution:

chisq.test(real_sample, p=reference_distribution)
Chi-squared test for given probabilities

data:  real_sample
X-squared = 2606.2, df = 11, p-value < 2.2e-16

Here, with a very small p-value (<2.2e-16), no way this sample comes from the reference distribution. So something is going on, the too distributions are too different to ignore it given the criteria we previously defined. Maybe the reference distribution was not reflecting correctly how the population is, maybe there were many categorization errors in the second dataset, or maybe something changed for customers between the time the first dataset and second dataset have been collected. There are many possible explanations that should be investigated, but anyway something is going on here.

Caveat about a too large sample size

If you already collected data before conducting sample size calculations, and you realize that you have really much more data than what you actually need, it may be a problem - but nothing unsolvable.

Indeed, in this case, the chi-square test may return a very small p-value even if the difference between the sample and the reference distribution is actually of no practical interest to you. If you're in this situation (sample size much larger than what you calculated) and are unsure on how to interpret the small p-value you get from your test, I'd suggest to have a look at the following pages: Sample size too large? and Are large data sets inappropriate for hypothesis testing?

Bibliography

You can find a thorough discussion of power calculations for the chi-squared tests in the chapter 7 of: Cohen, J. (1988). Statistical power analysis for the behavioral sciences (2nd ed). Routledge.

If you want to use other tools than R, there are many online video tutorial explaining on to do that using Gpower. You'll also find a comparison on how to perform power calculations in R and Python here, section "Chi-square goodness-of-fit": Perktold, J. (2013, March 17). joepy: Statistical Power in Statsmodels. Joepy. http://jpktd.blogspot.com/2013/03/statistical-power-in-statsmodels.html

$\endgroup$
5
  • $\begingroup$ Thank you, I will be reading through those links you kindly provided. In your answer you outlined that the most important first step is to identify the type of statistical test you wish to run - is there a scenario, say in political polling, where the goal is to make inferences on the populations voting preferences by sampling enough citizens to confidently make those inferences. I believe my use case is more aligned to this goal (understanding opinions/beliefs of our customer base rather than strictly comparing distributions). $\endgroup$
    – K-J
    Commented May 29, 2023 at 13:13
  • $\begingroup$ @K-J Then if you're not interested in comparing your sample to a hypothetical distribution, then you may not need to follow the advise I give in my answer (but hopefully it may be helpful to other people). In this case, to get an idea of "how reliable the sample is", a possibility is to use the MultinomCI method in the DescTools package rdocumentation.org/packages/DescTools/versions/0.99.48/topics/… that will give you confidence intervals around the proportions you get from your sample. I'll try to amend my answer to give an example of how to proceed. $\endgroup$
    – J-J-J
    Commented May 29, 2023 at 13:39
  • $\begingroup$ Your original answer is super helpful - I think you're likely 10 steps ahead of me as this is the kind of thing I might be needing to do but hadn't quite seen this as the approach to take. Hugely educational and I am sure others will also find it so. I'm very grateful for your help. $\endgroup$
    – K-J
    Commented May 29, 2023 at 13:52
  • $\begingroup$ @K-J absolutely no problem, it was useful for me to write this answer, because this is a procedure I use, but still haven't detailed a lot by writing (so it was the opportunity to put things down in writing) $\endgroup$
    – J-J-J
    Commented May 29, 2023 at 13:58
  • $\begingroup$ Great answer (+1) $\endgroup$ Commented Mar 16 at 21:46

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.