Connect with me on Open Science Framework | Contact me via LinkedIn
Depending on your machine it might be necessary to use right-click -> open in new browser window.
R analysis script presenting the results for exercise 6 in consumer behavior. These are the questions regarding Girard et al. (2019).
Beware: R is a context-sensitive language. Thus, ‘data’ will be interpreted not in the same way as ‘Data’ will.
In R most functionality is provided by additional packages.
Most of the packages are well-documented, See: https://cran.r-project.org/
The code chunk below first evaluates if the package pacman is already installed to your machine. If yes, the corresponding package will be loaded. If not, R will install the package.
Alternatively, you can do this manually first by executing install.packages(“pacman”) and then library(pacman).
The second line then loads the package pacman
The third line uses the function p_load() from the pacman package to install (if necessary) and load all packages that we provide as arguments (e.g., pwr, which provides functions for power analysis).
if(!"pacman" %in% rownames(installed.packages())) install.packages("pacman")
library(pacman)
pacman::p_load(tidyverse, dplyr, pwr, tidyselect, compute.es, WebPower)
Here is the R session info which gives you information on my machine, all loaded packages and their version:
sessionInfo()
## R version 3.6.3 (2020-02-29)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 18363)
##
## Matrix products: default
##
## locale:
## [1] LC_COLLATE=German_Germany.1252 LC_CTYPE=German_Germany.1252
## [3] LC_MONETARY=German_Germany.1252 LC_NUMERIC=C
## [5] LC_TIME=German_Germany.1252
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] compute.es_0.2-4 tidyselect_1.0.0 pwr_1.3-0 forcats_0.5.0
## [5] stringr_1.4.0 dplyr_0.8.5 purrr_0.3.3 readr_1.3.1
## [9] tidyr_1.0.2 tibble_2.1.3 ggplot2_3.3.0 tidyverse_1.3.0
## [13] pacman_0.5.1
##
## loaded via a namespace (and not attached):
## [1] xfun_0.12 haven_2.2.0 lattice_0.20-38 colorspace_1.4-1
## [5] vctrs_0.2.4 generics_0.0.2 htmltools_0.4.0 yaml_2.2.1
## [9] rlang_0.4.5 pillar_1.4.3 glue_1.3.2 withr_2.1.2
## [13] DBI_1.1.0 dbplyr_1.4.2 modelr_0.1.6 readxl_1.3.1
## [17] lifecycle_0.2.0 munsell_0.5.0 gtable_0.3.0 cellranger_1.1.0
## [21] rvest_0.3.5 codetools_0.2-16 evaluate_0.14 knitr_1.28
## [25] fansi_0.4.1 broom_0.5.5 Rcpp_1.0.3 scales_1.1.0
## [29] backports_1.1.5 jsonlite_1.6.1 fs_1.3.2 hms_0.5.3
## [33] digest_0.6.25 stringi_1.4.3 grid_3.6.3 cli_2.0.2
## [37] tools_3.6.3 magrittr_1.5 crayon_1.3.4 pkgconfig_2.0.3
## [41] xml2_1.2.5 reprex_0.3.0 lubridate_1.7.4 assertthat_0.2.1
## [45] rmarkdown_2.1 httr_1.4.1 rstudioapi_0.11 R6_2.4.1
## [49] nlme_3.1-145 compiler_3.6.3
How many respondents should one at minimum calculate for a replication of study 1’s results regarding perceived service value? Assumptions: equal split to scent vs. no scent conditions, \(\alpha\)=5%, \(\beta\)=5%, between-subjects ANOVA)
As we use an ANOVA here, the solution is very similar to Exercise 3 on Topolinski et al. (2014).
We have seen from our exercise that the program G*Power requires the effect size measure Cohen’s f (Cohen, 1988). The same hold for the pwr package, which we will again, use to conduct power analysis in R. Therefore, we first need to convert information provided by the JSR article into a sample estimate of f.
Information the article provides:
“[…] and service value, Mscented = 3.69, SD = 1.37 versus Munscented = 3.05, SD = 1.38, F(1, 195) = 14.521, p < .001, \(\eta^{2}_{p}\) = .069, than those in the unscented condition, […]”
From this we are able to extract:
This is all that we need to first calculate the observed effect size Cohen’s f (Cohen, 1988). According the Cohen (1988, p. 281) \(\eta^{2}_{p}\) can easily be converted to f by a simple formula: f= \(\sqrt{\frac{\eta^{2}}{1-\eta^{2}}}\) Therefore, we simply need to solve \(\sqrt{\frac{0.069}{1-0.069}}\)
We achieve this by using the next code chunk. Within this code chunk we use the sqrt() function (place the cursor in the function and press ‘F1’ to see help), which calculates the square root of a number. We feed this function with the value of \(\eta^{2}_{p}\)=0.069. We assign the results to an object that we call ‘Cohen_f’.
In the next line we call the object and simultaneously round the results to 4 digits. This is obtained by using the round() function.
Cohen_f <- sqrt(0.069 / (1 - 0.069))
round(Cohen_f, digits = 4)
## [1] 0.2722
We can see that the calculated effect size 0.2722 perfectly mirrors the one we have seen in the exercise slides using G*Power. A common classification for Cohen’s f is: [0.1 | 0.25[ - small effect, [0.25 | 0.4[ - medium effect, and [0.4 | 1] - large effect.
In the question we are asked for \(\beta\)=5%, which corresponds to a statistical power of 95%.
To estimate a minimum sample size n for the replication we apply the pwr.anova.test() function from the pwr package. This function needs us to provide 5 arguments to fill its parameters. These are (see help by pressing ‘F1’):
The function, furthermore, assumes us to set one of these arguments to NULL. By doing so, we tell the function to use the remaining 4 parameters to search for the value of the fifth. In our case, we are searching for ‘n’, therefore, we set ‘n=NULL’.
We assign the results of our power analysis to a new object named ‘results’. Then we call for its content.
results <- pwr.anova.test(k = 2, n = NULL, f = Cohen_f, sig.level = 0.05, power = 0.95)
results
Balanced one-way analysis of variance power calculation
k = 2
n = 88.63934
f = 0.2722386
sig.level = 0.05
power = 0.95
NOTE: n is number in each group
We can see that the calculated sample size per group 88.6393365 only closely mirrors the one we have seen in G*Power 3 (Faul, Erdfelder, Lang, & Buchner, 2007) at n=89. We have to round upwards to end up with 89. For the total sample size, we just multiply by 2, which gives 178.
In a last step we can visualize the relationship between the expected statistical power and different sample sizes.
For this purpose we apply the plot() function with the ‘results’ object and a catchy label for the x-axes as arguments.
plot(results, xlab = "sample size")
From this plot we can alternatively extract the same information for sample size planning.
Cohen, J. (1988). Statistical power analysis for the behavioral sciences (2nd ed.). Lawrence Erlbaum.
Faul, F., Erdfelder, E., Lang, A.-G., & Buchner, A. (2007). G* power 3: A flexible statistical power analysis program for the social, behavioral, and biomedical sciences. Behavior Research Methods, 39(2), 175–191. doi: 10.3758/BF03193146
Girard, A., Lichters, M., Sarstedt, M., & Biswas, D. (2019). Short- and long-term effects of nonconsciously processed ambient scents in a servicescape: Findings from two field experiments. Journal of Service Research, 22(4), 440–455. doi: 10.1177/1094670519842333
Topolinski, S., Lindner, S., & Freudenberg, A. (2014). Popcorn in the cinema: Oral interference sabotages advertising effects. Journal of Consumer Psychology, 24(2), 169–176. doi: 10.1016/j.jcps.2013.09.008