简体   繁体   中英

Compare treatment effects in three way interaction between two continuous variables and one categorical variable in R

I am trying to run a linear regression model which contains continuous variable A * continuous variables B * categorical variable (treatments with 4 levels). Data can be download here .

Model<-lm(H2O2~Treatment*(A*B), data=mydata)

Now I want to compare different treatment effects.

I know that lstrends can deal with continuous variable * categorical variable in linear model, but it could not work in my situation. I also tried to divide the data based on different treatment groups and created 4 different linear models to compare, that did not work either.

The equation you're estimating is:

在此处输入图像描述

There are six different treatment effects in which you could be interested - they comprise the pairwise differences among treatment categories given fixed values of A and B . Three of these are represented by comparisons of estimated categories versus the reference category. For example, to figure out the effect of HF versus HC (the reference), you would calculate:

Looking at the coefficients from your model:

b <- coef(Model)
b
    (Intercept)     TreatmentHF     TreatmentLF     TreatmentMF               A               B 
  -1.4318658015    1.5744952961    1.7649475644   -0.6971275663    0.0334782841    0.1528682774 
            A:B   TreatmentHF:A   TreatmentLF:A   TreatmentMF:A   TreatmentHF:B   TreatmentLF:B 
  -0.0022753098   -0.0313728254   -0.0342105088    0.0173173280   -0.1430777577   -0.1214230927 
  TreatmentMF:B TreatmentHF:A:B TreatmentLF:A:B TreatmentMF:A:B 
   0.0212295284    0.0025811227    0.0023565223   -0.0007721532 

You would want in R, something like

b[2] + b[8]*A + b[11]*B + b[14]*A*B

You would want to substitute in a wide range of combinations of A and B , which you could do by making a sequence of values of each going from the minimum to the maximum, and then crossing them.

a_seq <- seq(min(mydata$A), max(mydata$A), length=25)
b_seq <- seq(min(mydata$B), max(mydata$B), length=25)
eg <- expand.grid(A=a_seq, B=b_seq)
head(eg)
#          A    B
# 1  5.03000 4.34
# 2 10.01292 4.34
# 3 14.99583 4.34
# 4 19.97875 4.34
# 5 24.96167 4.34
# 6 29.94458 4.34

You could then make the treatment effect in this dataset.

library(dplyr)
eg <- eg %>% mutate(treat_HC_HF = b[2] + b[8]*A + b[11]*B + b[14]*A*B)

Then, you could plot it using a heatmap or similar.

ggplot(eg, aes(x=A, y=B, fill=treat_HC_HF)) + 
  geom_tile() + 
  scale_fill_viridis_c() + 
  theme_classic() + 
  labs(fill="Treatment\nEffect")

在此处输入图像描述

You could do this for the other comparisons as well. There are two things that you don't get from this directly that are. First, this doesn't tell you anything about where you actually observe A and B. Second it doesn't tell you whether any of these effects is statistically significant. The first problem you could solve more or less by only plotting those hypothetical values of A and B that are in the convex hull of A and B in the data.

library(geometry)
ch <- convhulln(mydata[,c("A", "B")])
eg <- eg %>% 
  mutate(inhull = inhulln(ch, cbind(A,B)))

eg %>% 
  filter(inhull) %>% 
  ggplot(aes(x=A, y=B, fill=treat_HC_HF)) + 
  geom_tile() + 
  scale_fill_viridis_c(limits = c(min(eg$treat_HC_HF), max(eg$treat_HC_HF))) + 
  theme_classic() + 
  labs(fill="Treatment\nEffect")

在此处输入图像描述

To calculate whether or not these are significant, you would have to do a bit more work. First, you'd have to get the standard error of each comparison. What you need is a matrix we'll call M that collects the values you multiply the coefficients by to get the treatment effect. So, in the above example, we would have the three pieces of information:

在此处输入图像描述

In R, we could get these with:

b_t <- b[c(2,8,11,14)]
V_t <- vcov(Model)[c(2,8,11,14), c(2,8,11,14)]
M <- cbind(1, eg$A, eg$B, eg$A*eg$B)

Then, we could calculate the standard error of the treatment effect as:

In R, we could do this and identify which treatment effects are significant (two-tailed 95% test) with:

eg <- eg %>% 
  mutate(se = sqrt(diag(M %*% V_t %*% t(M))), 
         sig = abs(treat_HC_HF/se) > pt(0.975, Model$df.residual))

Then we could plot only those effects that are in the convex hull and significant:

eg %>% 
  filter(inhull, sig) %>% 
  ggplot(aes(x=A, y=B, fill=treat_HC_HF)) + 
  geom_tile() + 
  scale_fill_viridis_c(limits = c(min(eg$treat_HC_HF), max(eg$treat_HC_HF))) + 
  theme_classic() + 
  labs(fill="Treatment\nEffect")

在此处输入图像描述

You would have to do this for each one of the six paired comparisons of levels of the treatment effects. This seems like a lot of work, but the model, despite the simplicity of estimating it, is quite complicated to interpret.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM