我想估算一个等式:
(其中条形表示变量的平均值......意思是,我想自动在Z和贬值版本的X之间进行交互。到目前为止,我只是事先手动贬低变量并估算:
lm(Y ~ .*Z, data= sdata)
这似乎有效,但我宁愿使用不需要手动贬低的解决方案,因为我还希望包含更复杂术语的方法,例如:
修改 根据要求,一个有效的代码示例,请注意,实际上我有大量(和变化)数量的X变量,因此我不想使用硬编码变体:
x1 <- runif(100)
x2 <- runif(100)
Z <- runif(100)
Y <- exp(x1) + exp(x2) + exp(z)
##current way of estimating the first equation:
sdata <- data.frame(Y=Y,Z=Z,x1=x1-mean(x1),x2=x2-mean(x2))
lm(Y ~ .*Z, data= sdata)
##basically what I want is that the following terms, and their interactions with Z are also used:
# X1^2 - mean(X1^2)
# X2^2 - mean(X2^2)
# X1*X2 - mean(X1*X2)
编辑2: 现在,我想要实现的基本上是什么
lm(Y ~ .^2*Z, data= sdata)
会这样做。但是,给定之前的demeaing表达式,例如:Z:X1:X2对应于:(x1-mean(x1))*(x2-mean(x2))
,而我想要的是x1*x2-mean(x1*x2)
答案 0 :(得分:2)
要在公式中显示该比例:
lm(mpg ~ cyl + scale(disp*hp, scale=F), data=mtcars)
Call:
lm(formula = mpg ~ cyl + scale(disp * hp, scale = F), data = mtcars)
Coefficients:
(Intercept) cyl scale(disp * hp, scale = F)
3.312e+01 -2.105e+00 -4.642e-05
现在进行比较,让我们在公式之外缩放交互:
mtcars$scaled_interaction <- with(mtcars, scale(disp*hp, scale=F))
lm(mpg ~ cyl + scaled_interaction, data=mtcars)
Call:
lm(formula = mpg ~ cyl + scaled_interaction, data = mtcars)
Coefficients:
(Intercept) cyl scaled_interaction
3.312e+01 -2.105e+00 -4.642e-05
至少在这些示例中,似乎公式内的scale
正在起作用。
为您的具体问题提供解决方案:
备选方案1:使用公式
# fit without Z
mod <- lm(Y ~ (.)^2, data= sdata[, names(sdata) != "Z" ])
vars <- attr(mod$terms, "term.labels")
vars <- gsub(":", "*", vars) # needed so that scale works later
vars <- paste0("scale(", vars, ", scale=F)")
newf <- as.formula(paste0("Y ~ ", paste0(vars, collapse = "+")))
# now interact with Z
f2 <- update.formula(newf, . ~ .*Z)
# This fives the following formula:
f2
Y ~ scale(x1, scale = F) + scale(x2, scale = F) + scale(x1*x2, scale = F) +
Z + scale(x1, scale = F):Z + scale(x2, scale = F):Z + scale(x1*x2, scale = F):Z
备选方案2:使用模型矩阵
# again fit without Z and get model matrix
mod <- lm(Y ~ (.)^2, data= sdata[, names(sdata) != "Z" ])
modmat <- apply(model.matrix(mod), 2, function(x) scale(x, scale=F))
此处,所有x
和相互作用都被贬低:
> head(modmat)
(Intercept) x1 x2 x1:x2
[1,] 0 0.1042908 -0.08989091 -0.01095459
[2,] 0 0.1611867 -0.32677059 -0.05425087
[3,] 0 0.2206845 0.29820499 0.06422944
[4,] 0 0.3462069 -0.15636463 -0.05571430
[5,] 0 0.3194451 -0.38668844 -0.12510551
[6,] 0 -0.4708222 -0.32502269 0.15144812
> round(colMeans(modmat), 2)
(Intercept) x1 x2 x1:x2
0 0 0 0
您可以按如下方式使用模型矩阵:
modmat <- modmat[, -1] # remove intercept
lm(sdata$Y ~ modmat*sdata$Z)
它不漂亮,但应该使用任意数量的解释变量。您还可以将Y
和Z
添加到矩阵中,以便输出看起来更漂亮(如果这是一个问题)。请注意,您也可以直接创建模型矩阵而无需拟合模型。我直接从装配好的模型中取出它,因为它已经适合第一种方法。
作为旁注,可能没有以更直接的方式实施,因为很难想象与贬值变量的相互作用相比,更有利于贬低相互作用的情况。
比较两种方法:
这里是两种方法的输出进行比较。如您所见,除系数名称外,一切都是相同的。
> lm(sdata$Y ~ modmat*sdata$Z)
Call:
lm(formula = sdata$Y ~ modmat * sdata$Z)
Coefficients:
(Intercept) modmatx1 modmatx2 modmatx1:x2 sdata$Z
4.33105 1.56455 1.43979 -0.09206 1.72901
modmatx1:sdata$Z modmatx2:sdata$Z modmatx1:x2:sdata$Z
0.25332 0.38155 -0.66292
> lm(f2, data=sdata)
Call:
lm(formula = f2, data = sdata)
Coefficients:
(Intercept) scale(x1, scale = F) scale(x2, scale = F)
4.33105 1.56455 1.43979
scale(x1 * x2, scale = F) Z scale(x1, scale = F):Z
-0.09206 1.72901 0.25332
scale(x2, scale = F):Z scale(x1 * x2, scale = F):Z
0.38155 -0.66292