richarddmorey / BayesFactor

BayesFactor R package for Bayesian data analysis with common statistical models.
https://richarddmorey.github.io/BayesFactor/
131 stars 48 forks source link

Time as a predictor and nonlinear regression #82

Open bastosfh opened 7 years ago

bastosfh commented 7 years ago

Hi Richard,

First of all, thank you very much for all the work with BayesFactor!

I've just started studing bayes data analysis and have little experience with fitting models to data, so my questions below may sound very noob. Nevertheless, I'd be very grateful if you could help me with three questions concerning generalTestBF.

I've included some code below to (hopefuly) help you understanding my questions.

  1. Can I use it to do a regression with one of the predictors being "time", i.e. repeated measures?
  2. Considering the posterior for the predictor fb_type-1: a median of -1.06 means that for every "1" feedback received there is a reduction of 1 in performance (similarly to a linear regression estimate)? Is that expected that fb_type-1 and fb_type-2 posteriors have the same values (except for the signs)?
  3. Given that my data is closer to "nonlinear" than "linear" (please, see the plot performance X block in the code below), is there a way of using a nonlinear model with generalTestBF?

Thank you very much in advance!

Best regards, Flavio

Libraries

library(ggplot2) library(BayesFactor)

Simulated data for 3 participants

Performance in a timing task

y1 <- c(300, 230, 200, 190, 170, 165, 160, 157, 159, 155) y2 <- c(280, 239, 210, 180, 160, 170, 172, 163, 158, 156) y3 <- c(350, 237, 213, 183, 161, 173, 175, 167, 161, 160)

Feedback type

fb_s2 <- c(1,1,1,1,2,2,1,1,2,1) fb_s1 <- c(1,2,1,2,2,1,1,1,2,1) fb_s3 <- c(1,1,1,1,1,1,2,1,1,2)

Create data frame

df <- data.frame(id = c(rep(1, 10), rep(2, 10), rep(3, 10)), # Participants block = 1:10, # Blocks of trials (i.e. the repeated measures) performance = c(y1, y2, y3), # Accuracy in a timing task fb_type = c(fb_s1, fb_s2, fb_s3)) # Type of feedback received

Plot performance X block

ggplot(data = df, aes(x = block, y = performance)) + geom_point()

Bayes regression

df$fb_type <- as.factor(df$fb_type) df$block <- as.factor(df$block) df$id <- as.factor(df$id)

all_bfs <- generalTestBF(performance ~ block + fb_type + block:fb_type + id, data = df, whichRandom = 'id', neverExclude='^id$')

Considering effect of ID as random and additive on top of other effects

plot(all_bfs / all_bfs['id'])

Get the posterior for one of the models

fit_bf <- lmBF(performance ~ block + fb_type + id, data = df, whichRandom = 'id') fit_posterior <- posterior(fit_bf, iterations = 10000) summary(fit_posterior)

Posterior distribution for feedback type as a predictor variable

plot(fit_posterior[ ,'fb_type-1']) plot(fit_posterior[ ,'fb_type-2'])

richarddmorey commented 7 years ago
  1. Yes; just include a predictor that indicates the "within" unit (e.g., people)

  2. The interpretation is that the "effect" of fb_type level 1 is decrement of -1 in performance on top of the grand mean. The reason why they have the same sign is that there is a sum-to-0 constraint in the fixed effects. You can think of it as meaning that there is only a single degree of freedom with two conditions.

  3. If by "non-linear" you mean models including (e.g.) polynomial terms in the predictors, yes. If by "non-linear" you mean models in which the expected value of a DV is not a linear combination of the predictors (e.g., logistic regression), then no.

bastosfh commented 7 years ago

Hi Richard,

Thank you very much for the quick and precise answer!

With respect to the polynomial terms as predictors, I've found an answer you gave in the "deprecated" R-forge forum for BayesFactor (https://r-forge.r-project.org/forum/forum.php?thread_id=29038&forum_id=1813&group_id=554). I though it would be interesting to paste it below, in case someone else comes looking for the same piece of information:


You just need to add the result of poly() to your data.frame. Here is an example (data taken from http://www.r-bloggers.com/polynomial-regression-techniques/):

Year <- c(1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969) Population <- c(4835, 4970, 5085, 5160, 5310, 5260, 5235, 5255, 5235, 5210, 5175)

Create data

sample1 <- data.frame(Year, Population) sample1$Year <- sample1$Year - 1964

Create polynomial covariates

X = poly(sample1$Year, 2, raw=TRUE) colnames(X) = c("one","two")

Add them to the data.frame

sample1 = cbind(X,sample1)

Perform the regression analysis (can also use generalTestBF)

regressionBF(Population ~ one + two, data = sample1)

Best wishes, Flavio