When estimating the effect of a categorical variable, such as in, for example, an ANOVA, bain by default drops the intercept. This seems like a logical decision, but results in seemingly unexpected behavior, because there is no warning message shown. Accordingly, the estimate as given in an lm model reflects the difference between two categories, while bain uses the same name to refer to the group specific mean. This issue becomes apparent in the following reprex.
# Load required packages
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(magrittr)
#> Warning: package 'magrittr' was built under R version 4.1.2
library(bain)
set.seed(1)
# Load data and specify sex as a factor variable
dat1 <- sesamesim %>%
mutate(sex = factor(sex, labels = c("boy", "girl")))
# Fit model
mod1 <- lm(postnumb ~ sex, dat1)
# Summary of model
summary(mod1)
#>
#> Call:
#> lm(formula = postnumb ~ sex, data = dat1)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -30.096 -8.096 -0.856 8.144 32.904
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 30.096 1.175 25.616 <2e-16 ***
#> sexgirl -1.240 1.628 -0.761 0.447
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 12.6 on 238 degrees of freedom
#> Multiple R-squared: 0.00243, Adjusted R-squared: -0.001761
#> F-statistic: 0.5799 on 1 and 238 DF, p-value: 0.4471
# Note that sexgirl here reflects the difference with sexboy
# If we use this model in bain, and specify a negative
# effect for sexgirl (which seems like a logical thing to do),
# this results in unexpected behavior, because bain implicitly
# transforms the intercept and difference into two separate means.
# However, this only becomes apparent after inspecting the summary
# of the bain output.
bf1 <- bain(mod1, "sexgirl < 0")
bf1
#> Bayesian informative hypothesis testing for an object of class lm (ANOVA):
#>
#> Fit Com BF.u BF.c PMPa PMPb
#> H1 0.000 0.500 0.000 0.000 1.000 0.000
#> Hu 1.000
#>
#> Hypotheses:
#> H1: sexgirl<0
#>
#> Note: BF.u denotes the Bayes factor of the hypothesis at hand versus the unconstrained hypothesis Hu. BF.c denotes the Bayes factor of the hypothesis at hand versus its complement.
# Fit is 0, which seems weird, because it is in line with the effect
# as estimated by the `lm` function.
# Only when calling summary(mod1) it becomes apparent that `sexgirl`
# suddenly refers to the mean of the girls, rather than the difference
# between boys and girls.
summary(bf1)
#> Parameter n Estimate lb ub
#> 1 sexboy 115 30.09565 27.79295 32.39836
#> 2 sexgirl 125 28.85600 26.64732 31.06468
Created on 2022-03-09 by the reprex package (v2.0.0)
On a related note, researchers may also manually dummy code their categories. If this is the case, bain does not remove the intercept, but estimates the difference. However, this ignores the fact that there are multiple groups involved, which results in an inconsistent Bayes factor (Hoijtink, Gu & Mulder, 2019). Is it indeed problematic to create numeric dummy variables, and estimate the effect of these using bain, because the resulting Bayes factors are highly similar (see reprex below). If this is actually a problematic way to estimate the effects of categorical variables, it may be worthwhile to let bain recognize numeric dummy variables, and display a warning if these are observed.
# Load required packages
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(magrittr)
#> Warning: package 'magrittr' was built under R version 4.1.2
library(bain)
set.seed(1)
# Make the site variable a factor
bf_group_means <- sesamesim %>%
mutate(site = as.factor(site)) %$%
lm(postnumb ~ site + prenumb) %>%
bain("site3 < site1 < site2 & prenumb > 0")
bf_group_means
#> Bayesian informative hypothesis testing for an object of class lm (ANCOVA):
#>
#> Fit Com BF.u BF.c PMPa PMPb
#> H1 0.443 0.057 7.794 13.189 1.000 0.886
#> Hu 0.114
#>
#> Hypotheses:
#> H1: site3<site1<site2&prenumb>0
#>
#> Note: BF.u denotes the Bayes factor of the hypothesis at hand versus the unconstrained hypothesis Hu. BF.c denotes the Bayes factor of the hypothesis at hand versus its complement.
# Create dummies manually, I'll use site = 1 as the reference
bf_differences <- sesamesim %>%
mutate(site1 = ifelse(site == 1, 1, 0),
site2 = ifelse(site == 2, 1, 0),
site3 = ifelse(site == 3, 1, 0),
site4 = ifelse(site == 4, 1, 0),
site5 = ifelse(site == 5, 1, 0)) %$%
lm(postnumb ~ site2 + site3 + site4 + site5 + prenumb) %>%
bain("site3 < 0 & site2 > 0 & prenumb > 0")
bf_differences
#> Bayesian informative hypothesis testing for an object of class lm (continuous predictors):
#>
#> Fit Com BF.u BF.c PMPa PMPb
#> H1 0.448 0.055 8.118 13.888 1.000 0.890
#> Hu 0.110
#>
#> Hypotheses:
#> H1: site3<0&site2>0&prenumb>0
#>
#> Note: BF.u denotes the Bayes factor of the hypothesis at hand versus the unconstrained hypothesis Hu. BF.c denotes the Bayes factor of the hypothesis at hand versus its complement.
# Almost identical fit & complexity
summary(bf_group_means)
#> Parameter n Estimate lb ub
#> 1 site1 60 27.4293820 25.1603844 29.698380
#> 2 site2 55 34.9818244 32.5529993 37.410650
#> 3 site3 64 27.6904082 25.4002689 29.980548
#> 4 site4 43 26.9840163 24.3250440 29.642989
#> 5 site5 18 31.4298837 27.3413936 35.518374
#> 6 prenumb 240 0.7159311 0.5986552 0.833207
summary(bf_differences)
#> Parameter n Estimate lb ub
#> 1 site3 240 0.2610262 -3.0455948 3.567647
#> 2 site2 240 7.5524424 4.3017084 10.803176
#> 3 prenumb 240 0.7159311 0.5986552 0.833207
# In the latter, the grouping structure is ignored
Created on 2022-03-09 by the reprex package (v2.0.0)
When estimating the effect of a categorical variable, such as in, for example, an ANOVA,
bainby default drops the intercept. This seems like a logical decision, but results in seemingly unexpected behavior, because there is no warning message shown. Accordingly, the estimate as given in anlmmodel reflects the difference between two categories, whilebainuses the same name to refer to the group specific mean. This issue becomes apparent in the following reprex.Created on 2022-03-09 by the reprex package (v2.0.0)
On a related note, researchers may also manually dummy code their categories. If this is the case,
baindoes not remove the intercept, but estimates the difference. However, this ignores the fact that there are multiple groups involved, which results in an inconsistent Bayes factor (Hoijtink, Gu & Mulder, 2019). Is it indeed problematic to create numeric dummy variables, and estimate the effect of these usingbain, because the resulting Bayes factors are highly similar (see reprex below). If this is actually a problematic way to estimate the effects of categorical variables, it may be worthwhile to letbainrecognize numeric dummy variables, and display a warning if these are observed.Created on 2022-03-09 by the reprex package (v2.0.0)