Getting ready: load packages and some data.

library(tidyverse)
library(easystats)
library(pwr)

chem <- read_csv('winter_2016_senses_valence.csv') %>% 
  filter(Modality %in% c('Taste', 'Smell'))

Dance of the p-values… in R

We’re going to simulate a large (n = 100000) set of data as a population and then take some small (n = 30) samples from it.

set.seed(100)
x <- round(rnorm(100000, mean = 50, sd = 10), 0)
mean(x)
[1] 50.01609
sd(x)
[1] 9.995032
range(x)
[1]  5 94
hist(x)

Now to sample:

d <- tibble(df01 = sample(x, 30),
            df02 = sample(x, 30),
            df03 = sample(x, 30),
            df04 = sample(x, 30),
            df05 = sample(x, 30),
            df06 = sample(x, 30),
            df07 = sample(x, 30),
            df08 = sample(x, 30),
            df09 = sample(x, 30),
            df10 = sample(x, 30))

and the plot:

d %>% pivot_longer(df01:df10, names_to = "sample", values_to = "score") %>%
  group_by(sample) %>%
  summarise(mean = mean(score),
            n = n(),
            sd = sd(score),
            se = sd/sqrt(n),
            CI = 1.96*se) %>%
  ggplot(aes(y = mean, x = sample))+
  geom_hline(yintercept = 50, linetype = 2)+
  geom_pointrange(aes(x = sample, y = mean, ymin = mean-CI, ymax = mean+CI),
                  color = "blue")+
  scale_y_continuous(limits = c(35, 65), breaks = c(40, 50, 60))+
  theme_bw()+
  coord_flip()

and now a ‘dance of the t-values’

set.seed(42)
t.test(rnorm(10), rnorm(10))

    Welch Two Sample t-test

data:  rnorm(10) and rnorm(10)
t = 1.2268, df = 13.421, p-value = 0.241
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.5369389  1.9584459
sample estimates:
 mean of x  mean of y 
 0.5472968 -0.1634567 
t.test(rnorm(10), rnorm(10))

    Welch Two Sample t-test

data:  rnorm(10) and rnorm(10)
t = 0.36582, df = 17.977, p-value = 0.7188
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.8814711  1.2531201
sample estimates:
 mean of x  mean of y 
-0.1780795 -0.3639041 
t.test(rnorm(10), rnorm(10))

    Welch Two Sample t-test

data:  rnorm(10) and rnorm(10)
t = -0.082117, df = 16.257, p-value = 0.9356
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.0340503  0.9568318
sample estimates:
  mean of x   mean of y 
-0.02021535  0.01839391 
t.test(rnorm(10), rnorm(10))

    Welch Two Sample t-test

data:  rnorm(10) and rnorm(10)
t = 2.3062, df = 17.808, p-value = 0.03335
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.06683172 1.44707262
sample estimates:
 mean of x  mean of y 
 0.5390768 -0.2178754 
set.seed(42)
t.test(rnorm(10, mean = 1), rnorm(10, mean = 0))

    Welch Two Sample t-test

data:  rnorm(10, mean = 1) and rnorm(10, mean = 0)
t = 2.9527, df = 13.421, p-value = 0.01089
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.4630611 2.9584459
sample estimates:
 mean of x  mean of y 
 1.5472968 -0.1634567 
t.test(rnorm(10, mean = 1), rnorm(10, mean = 0))

    Welch Two Sample t-test

data:  rnorm(10, mean = 1) and rnorm(10, mean = 0)
t = 2.3345, df = 17.977, p-value = 0.03137
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.1185289 2.2531201
sample estimates:
 mean of x  mean of y 
 0.8219205 -0.3639041 
t.test(rnorm(10, mean = 1), rnorm(10, mean = 0))

    Welch Two Sample t-test

data:  rnorm(10, mean = 1) and rnorm(10, mean = 0)
t = 2.0448, df = 16.257, p-value = 0.05742
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.03405031  1.95683178
sample estimates:
 mean of x  mean of y 
0.97978465 0.01839391 
t.test(rnorm(10, mean = 1), rnorm(10, mean = 0))

    Welch Two Sample t-test

data:  rnorm(10, mean = 1) and rnorm(10, mean = 0)
t = 5.3528, df = 17.808, p-value = 4.513e-05
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 1.066832 2.447073
sample estimates:
 mean of x  mean of y 
 1.5390768 -0.2178754 

Planning for Power in R

pwr.r.test(r = .30, sig.level = .05, power = .80, alternative = "two.sided")

     approximate correlation power calculation (arctangh transformation) 

              n = 84.07364
              r = 0.3
      sig.level = 0.05
          power = 0.8
    alternative = two.sided
pwr.t.test(d = 1, power = .8, type = "two.sample", alternative = "two.sided")

     Two-sample t test power calculation 

              n = 16.71472
              d = 1
      sig.level = 0.05
          power = 0.8
    alternative = two.sided

NOTE: n is number in *each* group
pwr.anova.test(k = 3, f = .25, power = .8)           

     Balanced one-way analysis of variance power calculation 

              k = 3
              n = 52.3966
              f = 0.25
      sig.level = 0.05
          power = 0.8

NOTE: n is number in each group
pwr.f2.test(u = 6, f2 = 0.15, power = .8) #whole model, based on R2

     Multiple regression power calculation 

              u = 6
              v = 90.30998
             f2 = 0.15
      sig.level = 0.05
          power = 0.8

95% CI for groups

chem %>% group_by(Modality) %>%
  summarise(mean = mean(Val),
            n = n(),
            sd = sd(Val),
            se = sd/sqrt(n),
            CI = 1.96*se)

plotting means and CIs

chem %>% group_by(Modality) %>%
  summarise(mean = mean(Val),
            n = n(),
            sd = sd(Val),
            se = sd/sqrt(n),
            CI = 1.96*se) %>%
  ggplot(aes(x = Modality, y = mean))+
  geom_point()+
  geom_errorbar(aes(ymin = mean-CI, ymax = mean+CI))+
  theme_bw()

Or we can try a different way, using stat_summary()


library(Hmisc)

chem %>% ggplot(aes(x = Modality, y = Val))+
  stat_summary(fun.data = "mean_cl_normal",
               size= 0.3, geom = "pointrange")+
  theme_bw()

NA

Cohen’s d

cohens_d(Val ~ Modality, data = chem)
Cohen's d |         95% CI
--------------------------
-1.07     | [-1.58, -0.55]

- Estimated using pooled SD.

Equivalence Testing

library(TOSTER)

chem_summary <- chem %>% group_by(Modality) %>%
  summarise(mean = mean(Val),
            n = n(),
            sd = sd(Val),
            se = sd/sqrt(n),
            CI = 1.96*se)

t_TOST(Val ~ Modality, data = chem,
       eqb = .4)

Welch Two Sample t-test

The equivalence test was non-significant, t(44.94) = 0.78, p = 0.22
The null hypothesis test was significant, t(44.94) = -4.19, p < 0.01
NHST: reject null significance hypothesis that the effect is equal to zero 
TOST: don't reject null equivalence hypothesis

TOST Results 

Effect Sizes 
Note: SMD confidence intervals are an approximation. See vignette("SMD_calcs").

Back to regression

We’ll now turn to some of the examples from Winter Ch. 11

library(broom)

icon <- read_csv('perry_winter_2017_iconicity.csv')

icon <- icon %>% mutate(SER_z = scale(SER),
                        CorteseImag_z = scale(CorteseImag),
                        Syst_z = scale(Syst),
                        Freq_z = scale(Freq))

Now to run a model and clean up the output…

icon_mdl_z <- lm(Iconicity ~ SER_z + CorteseImag_z +
                   Syst_z + Freq_z, data = icon)

tidy(icon_mdl_z) %>% 
  mutate(p.value = base::format.pval(p.value, 4),
         estimate = round(estimate, 2),
         std.error = round(std.error, 2),
         statistic = round(statistic, 2))

Or we can use the model_parameters() funcation from easystats’s parameters package.

model_parameters(icon_mdl_z)
Parameter     | Coefficient |   SE |         95% CI | t(984) |      p
---------------------------------------------------------------------
(Intercept)   |        1.15 | 0.03 | [ 1.08,  1.21] |  33.34 | < .001
SER z         |        0.53 | 0.04 | [ 0.45,  0.61] |  12.52 | < .001
CorteseImag z |       -0.42 | 0.04 | [-0.50, -0.34] | -10.72 | < .001
Syst z        |        0.06 | 0.03 | [-0.01,  0.12] |   1.79 | 0.074 
Freq z        |       -0.36 | 0.11 | [-0.58, -0.14] |  -3.20 | 0.001 

plotting time!

mycoefs <- tidy(icon_mdl_z, conf.int = T) %>%
  filter(term != '(Intercept)')

mycoefs %>% ggplot(aes(x = reorder(term, estimate), y = estimate))+
  geom_point()+
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = .2)+
  geom_hline(yintercept = 0, linetype = 2)+
  labs(x = NULL, y = 'Beta coefficient estimate')+
  coord_flip()+
  theme_minimal()

or…

model_parameters(icon_mdl_z) |> plot()

LS0tDQp0aXRsZTogIkVmZmVjdCBTaXplcyBhbmQgU3RhdGlzdGljYWwgSW5mZXJlbmNlcyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCkdldHRpbmcgcmVhZHk6IGxvYWQgcGFja2FnZXMgYW5kIHNvbWUgZGF0YS4NCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZWFzeXN0YXRzKQ0KbGlicmFyeShwd3IpDQoNCmNoZW0gPC0gcmVhZF9jc3YoJ3dpbnRlcl8yMDE2X3NlbnNlc192YWxlbmNlLmNzdicpICU+JSANCiAgZmlsdGVyKE1vZGFsaXR5ICVpbiUgYygnVGFzdGUnLCAnU21lbGwnKSkNCmBgYA0KIyBEYW5jZSBvZiB0aGUgcC12YWx1ZXMuLi4gaW4gUg0KV2UncmUgZ29pbmcgdG8gc2ltdWxhdGUgYSBsYXJnZSAobiA9IDEwMDAwMCkgc2V0IG9mIGRhdGEgYXMgYSAqcG9wdWxhdGlvbiogYW5kIHRoZW4gdGFrZSBzb21lIHNtYWxsIChuID0gMzApIHNhbXBsZXMgZnJvbSBpdC4NCmBgYHtyfQ0Kc2V0LnNlZWQoMTAwKQ0KeCA8LSByb3VuZChybm9ybSgxMDAwMDAsIG1lYW4gPSA1MCwgc2QgPSAxMCksIDApDQptZWFuKHgpDQpzZCh4KQ0KcmFuZ2UoeCkNCmhpc3QoeCkNCg0KYGBgDQoNCk5vdyB0byBzYW1wbGU6DQoNCmBgYHtyfQ0KZCA8LSB0aWJibGUoZGYwMSA9IHNhbXBsZSh4LCAzMCksDQogICAgICAgICAgICBkZjAyID0gc2FtcGxlKHgsIDMwKSwNCiAgICAgICAgICAgIGRmMDMgPSBzYW1wbGUoeCwgMzApLA0KICAgICAgICAgICAgZGYwNCA9IHNhbXBsZSh4LCAzMCksDQogICAgICAgICAgICBkZjA1ID0gc2FtcGxlKHgsIDMwKSwNCiAgICAgICAgICAgIGRmMDYgPSBzYW1wbGUoeCwgMzApLA0KICAgICAgICAgICAgZGYwNyA9IHNhbXBsZSh4LCAzMCksDQogICAgICAgICAgICBkZjA4ID0gc2FtcGxlKHgsIDMwKSwNCiAgICAgICAgICAgIGRmMDkgPSBzYW1wbGUoeCwgMzApLA0KICAgICAgICAgICAgZGYxMCA9IHNhbXBsZSh4LCAzMCkpDQpgYGANCg0KYW5kIHRoZSBwbG90Og0KDQpgYGB7cn0NCmQgJT4lIHBpdm90X2xvbmdlcihkZjAxOmRmMTAsIG5hbWVzX3RvID0gInNhbXBsZSIsIHZhbHVlc190byA9ICJzY29yZSIpICU+JQ0KICBncm91cF9ieShzYW1wbGUpICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oc2NvcmUpLA0KICAgICAgICAgICAgbiA9IG4oKSwNCiAgICAgICAgICAgIHNkID0gc2Qoc2NvcmUpLA0KICAgICAgICAgICAgc2UgPSBzZC9zcXJ0KG4pLA0KICAgICAgICAgICAgQ0kgPSAxLjk2KnNlKSAlPiUNCiAgZ2dwbG90KGFlcyh5ID0gbWVhbiwgeCA9IHNhbXBsZSkpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1MCwgbGluZXR5cGUgPSAyKSsNCiAgZ2VvbV9wb2ludHJhbmdlKGFlcyh4ID0gc2FtcGxlLCB5ID0gbWVhbiwgeW1pbiA9IG1lYW4tQ0ksIHltYXggPSBtZWFuK0NJKSwNCiAgICAgICAgICAgICAgICAgIGNvbG9yID0gImJsdWUiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMzUsIDY1KSwgYnJlYWtzID0gYyg0MCwgNTAsIDYwKSkrDQogIHRoZW1lX2J3KCkrDQogIGNvb3JkX2ZsaXAoKQ0KYGBgDQojIGFuZCBub3cgYSAnZGFuY2Ugb2YgdGhlIHQtdmFsdWVzJyANCg0KYGBge3J9DQpzZXQuc2VlZCg0MikNCnQudGVzdChybm9ybSgxMCksIHJub3JtKDEwKSkNCnQudGVzdChybm9ybSgxMCksIHJub3JtKDEwKSkNCnQudGVzdChybm9ybSgxMCksIHJub3JtKDEwKSkNCnQudGVzdChybm9ybSgxMCksIHJub3JtKDEwKSkNCg0Kc2V0LnNlZWQoNDIpDQp0LnRlc3Qocm5vcm0oMTAsIG1lYW4gPSAxKSwgcm5vcm0oMTAsIG1lYW4gPSAwKSkNCnQudGVzdChybm9ybSgxMCwgbWVhbiA9IDEpLCBybm9ybSgxMCwgbWVhbiA9IDApKQ0KdC50ZXN0KHJub3JtKDEwLCBtZWFuID0gMSksIHJub3JtKDEwLCBtZWFuID0gMCkpDQp0LnRlc3Qocm5vcm0oMTAsIG1lYW4gPSAxKSwgcm5vcm0oMTAsIG1lYW4gPSAwKSkNCmBgYA0KDQojIFBsYW5uaW5nIGZvciBQb3dlciBpbiBSDQoNCmBgYHtyfQ0KcHdyLnIudGVzdChyID0gLjMwLCBzaWcubGV2ZWwgPSAuMDUsIHBvd2VyID0gLjgwLCBhbHRlcm5hdGl2ZSA9ICJ0d28uc2lkZWQiKQ0KcHdyLnQudGVzdChkID0gMSwgcG93ZXIgPSAuOCwgdHlwZSA9ICJ0d28uc2FtcGxlIiwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikNCnB3ci5hbm92YS50ZXN0KGsgPSAzLCBmID0gLjI1LCBwb3dlciA9IC44KSAgICAgICAgICAgDQpwd3IuZjIudGVzdCh1ID0gNiwgZjIgPSAwLjE1LCBwb3dlciA9IC44KSAjd2hvbGUgbW9kZWwsIGJhc2VkIG9uIFIyDQpgYGANCg0KDQojIDk1JSBDSSBmb3IgZ3JvdXBzDQoNCmBgYHtyfQ0KY2hlbSAlPiUgZ3JvdXBfYnkoTW9kYWxpdHkpICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oVmFsKSwNCiAgICAgICAgICAgIG4gPSBuKCksDQogICAgICAgICAgICBzZCA9IHNkKFZhbCksDQogICAgICAgICAgICBzZSA9IHNkL3NxcnQobiksDQogICAgICAgICAgICBDSSA9IDEuOTYqc2UpDQpgYGANCg0KIyBwbG90dGluZyBtZWFucyBhbmQgQ0lzDQoNCmBgYHtyfQ0KY2hlbSAlPiUgZ3JvdXBfYnkoTW9kYWxpdHkpICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oVmFsKSwNCiAgICAgICAgICAgIG4gPSBuKCksDQogICAgICAgICAgICBzZCA9IHNkKFZhbCksDQogICAgICAgICAgICBzZSA9IHNkL3NxcnQobiksDQogICAgICAgICAgICBDSSA9IDEuOTYqc2UpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBNb2RhbGl0eSwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbi1DSSwgeW1heCA9IG1lYW4rQ0kpKSsNCiAgdGhlbWVfYncoKQ0KYGBgDQpPciB3ZSBjYW4gdHJ5IGEgZGlmZmVyZW50IHdheSwgdXNpbmcgYHN0YXRfc3VtbWFyeSgpYA0KDQpgYGB7cn0NCg0KbGlicmFyeShIbWlzYykNCg0KY2hlbSAlPiUgZ2dwbG90KGFlcyh4ID0gTW9kYWxpdHksIHkgPSBWYWwpKSsNCiAgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gIm1lYW5fY2xfbm9ybWFsIiwNCiAgICAgICAgICAgICAgIHNpemU9IDAuMywgZ2VvbSA9ICJwb2ludHJhbmdlIikrDQogIHRoZW1lX2J3KCkNCiAgDQpgYGANCg0KIyBDb2hlbidzIGQNCg0KYGBge3J9DQpjb2hlbnNfZChWYWwgfiBNb2RhbGl0eSwgZGF0YSA9IGNoZW0pDQpgYGANCg0KIyBFcXVpdmFsZW5jZSBUZXN0aW5nDQoNCmBgYHtyfQ0KbGlicmFyeShUT1NURVIpDQoNCmNoZW1fc3VtbWFyeSA8LSBjaGVtICU+JSBncm91cF9ieShNb2RhbGl0eSkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihWYWwpLA0KICAgICAgICAgICAgbiA9IG4oKSwNCiAgICAgICAgICAgIHNkID0gc2QoVmFsKSwNCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChuKSwNCiAgICAgICAgICAgIENJID0gMS45NipzZSkNCg0KdF9UT1NUKFZhbCB+IE1vZGFsaXR5LCBkYXRhID0gY2hlbSwNCiAgICAgICBlcWIgPSAuNCkNCg0KYGBgDQoNCiMgQmFjayB0byByZWdyZXNzaW9uDQpXZSdsbCBub3cgdHVybiB0byBzb21lIG9mIHRoZSBleGFtcGxlcyBmcm9tIFdpbnRlciBDaC4gMTENCg0KYGBge3J9DQpsaWJyYXJ5KGJyb29tKQ0KDQppY29uIDwtIHJlYWRfY3N2KCdwZXJyeV93aW50ZXJfMjAxN19pY29uaWNpdHkuY3N2JykNCg0KaWNvbiA8LSBpY29uICU+JSBtdXRhdGUoU0VSX3ogPSBzY2FsZShTRVIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgQ29ydGVzZUltYWdfeiA9IHNjYWxlKENvcnRlc2VJbWFnKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RfeiA9IHNjYWxlKFN5c3QpLA0KICAgICAgICAgICAgICAgICAgICAgICAgRnJlcV96ID0gc2NhbGUoRnJlcSkpDQpgYGANCg0KTm93IHRvIHJ1biBhIG1vZGVsIGFuZCBjbGVhbiB1cCB0aGUgb3V0cHV0Li4uDQoNCmBgYHtyfQ0KaWNvbl9tZGxfeiA8LSBsbShJY29uaWNpdHkgfiBTRVJfeiArIENvcnRlc2VJbWFnX3ogKw0KICAgICAgICAgICAgICAgICAgIFN5c3RfeiArIEZyZXFfeiwgZGF0YSA9IGljb24pDQoNCnRpZHkoaWNvbl9tZGxfeikgJT4lIA0KICBtdXRhdGUocC52YWx1ZSA9IGJhc2U6OmZvcm1hdC5wdmFsKHAudmFsdWUsIDQpLA0KICAgICAgICAgZXN0aW1hdGUgPSByb3VuZChlc3RpbWF0ZSwgMiksDQogICAgICAgICBzdGQuZXJyb3IgPSByb3VuZChzdGQuZXJyb3IsIDIpLA0KICAgICAgICAgc3RhdGlzdGljID0gcm91bmQoc3RhdGlzdGljLCAyKSkNCmBgYA0KDQpPciB3ZSBjYW4gdXNlIHRoZSBgbW9kZWxfcGFyYW1ldGVycygpYCBmdW5jYXRpb24gZnJvbSBgZWFzeXN0YXRzYCdzIGBwYXJhbWV0ZXJzYCBwYWNrYWdlLg0KDQpgYGB7cn0NCm1vZGVsX3BhcmFtZXRlcnMoaWNvbl9tZGxfeikNCmBgYA0KcGxvdHRpbmcgdGltZSENCg0KYGBge3J9DQpteWNvZWZzIDwtIHRpZHkoaWNvbl9tZGxfeiwgY29uZi5pbnQgPSBUKSAlPiUNCiAgZmlsdGVyKHRlcm0gIT0gJyhJbnRlcmNlcHQpJykNCg0KbXljb2VmcyAlPiUgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcih0ZXJtLCBlc3RpbWF0ZSksIHkgPSBlc3RpbWF0ZSkpKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBjb25mLmxvdywgeW1heCA9IGNvbmYuaGlnaCksIHdpZHRoID0gLjIpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gJ0JldGEgY29lZmZpY2llbnQgZXN0aW1hdGUnKSsNCiAgY29vcmRfZmxpcCgpKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpvci4uLg0KDQpgYGB7cn0NCm1vZGVsX3BhcmFtZXRlcnMoaWNvbl9tZGxfeikgfD4gcGxvdCgpDQpgYGANCg0K