如何根据分组的行进行回归并循环列?
How to make regression based on grouped rows and loop over columns?
我想要做的是执行一个回归循环,该循环始终具有相同的预测变量但循环响应(此处:y1、y2 和 y3)。问题是我希望它也对分组变量的每个类别完成。在下面的示例数据中,我想对所有三个 y 变量进行 y_i=x 回归,这将导致三个回归。但我希望这对 group=a、group=b 和 group=c 分别完成,从而产生 9 种不同的回归(最好存储为列表)。无法弄清楚该怎么做!谁知道如何做到这一点?
到目前为止,我的想法可能是做一个 for 循环或 lapply 结合 dplyr::group_by,但无法让它工作。
示例数据(我有一个更大的数据集用于实际分析)。
set.seed(123)
dat <- data.frame(group=c(rep("a",10), rep("b",10), rep("c",10)),
x=rnorm(30), y1=rnorm(30), y2=rnorm(30), y3=rnorm(30))
1) 在 nlme 中使用 lmList
(R 自带,因此您不必安装它)。
library(nlme)
regs <- lmList(cbind(y1, y2, y3) ~ x | group, dat)
给出一个 lmList
对象,每个组都有一个组件。我们显示组 a
的组件,其他组类似。
> regs$a
Call:
lm(formula = object, data = dat, na.action = na.action)
Coefficients:
y1 y2 y3
(Intercept) 0.2943 0.1395 0.4539
x 0.3721 -0.2206 -0.2255
2) 另一种方法是整体执行一个 lm
给出具有与上述相同系数的 lm
对象。
lm(cbind(y1, y2, y3) ~ group + x:group + 0, dat)
3) 我们还可以使用几个列表理解包之一。这给出了 9 个组件的列表。组件的名称标识使用的组合,就像每个主要组件中的调用组件(显示在输出的 Call: 行中)一样。请注意,当前 CRAN 版本是 0.1.0,但下面的代码依赖于 listcompr 0.1.1,它可以从 github 获得,直到它被放入 CRAN。
# install.github("patrickroocks/listcompr")
library(listcompr)
packageVersion("listcompr") # need version 0.1.1 or later
regs <- gen.named.list("{y}.{g}",
do.call("lm",
list(reformulate("x", y), quote(dat), subset = bquote(dat$group == .(g)))
), y = c("y1", "y2", "y3"), g = unique(dat$group)
)
如果您不介意输出中的 Call: 行描述性较差,则可以将其简化为:
gen.named.list("{y}.{g}", lm(reformulate("x", y), dat, subset = group == g),
y = c("y1", "y2", "y3"), g = unique(dat$group))
备注
从有两个 y2 的问题中更正输入。
set.seed(123)
dat <- data.frame(group=c(rep("a",10), rep("b",10), rep("c",10)),
x=rnorm(30), y1=rnorm(30), y2=rnorm(30), y3=rnorm(30))
我想要做的是执行一个回归循环,该循环始终具有相同的预测变量但循环响应(此处:y1、y2 和 y3)。问题是我希望它也对分组变量的每个类别完成。在下面的示例数据中,我想对所有三个 y 变量进行 y_i=x 回归,这将导致三个回归。但我希望这对 group=a、group=b 和 group=c 分别完成,从而产生 9 种不同的回归(最好存储为列表)。无法弄清楚该怎么做!谁知道如何做到这一点?
到目前为止,我的想法可能是做一个 for 循环或 lapply 结合 dplyr::group_by,但无法让它工作。
示例数据(我有一个更大的数据集用于实际分析)。
set.seed(123)
dat <- data.frame(group=c(rep("a",10), rep("b",10), rep("c",10)),
x=rnorm(30), y1=rnorm(30), y2=rnorm(30), y3=rnorm(30))
1) 在 nlme 中使用 lmList
(R 自带,因此您不必安装它)。
library(nlme)
regs <- lmList(cbind(y1, y2, y3) ~ x | group, dat)
给出一个 lmList
对象,每个组都有一个组件。我们显示组 a
的组件,其他组类似。
> regs$a
Call:
lm(formula = object, data = dat, na.action = na.action)
Coefficients:
y1 y2 y3
(Intercept) 0.2943 0.1395 0.4539
x 0.3721 -0.2206 -0.2255
2) 另一种方法是整体执行一个 lm
给出具有与上述相同系数的 lm
对象。
lm(cbind(y1, y2, y3) ~ group + x:group + 0, dat)
3) 我们还可以使用几个列表理解包之一。这给出了 9 个组件的列表。组件的名称标识使用的组合,就像每个主要组件中的调用组件(显示在输出的 Call: 行中)一样。请注意,当前 CRAN 版本是 0.1.0,但下面的代码依赖于 listcompr 0.1.1,它可以从 github 获得,直到它被放入 CRAN。
# install.github("patrickroocks/listcompr")
library(listcompr)
packageVersion("listcompr") # need version 0.1.1 or later
regs <- gen.named.list("{y}.{g}",
do.call("lm",
list(reformulate("x", y), quote(dat), subset = bquote(dat$group == .(g)))
), y = c("y1", "y2", "y3"), g = unique(dat$group)
)
如果您不介意输出中的 Call: 行描述性较差,则可以将其简化为:
gen.named.list("{y}.{g}", lm(reformulate("x", y), dat, subset = group == g),
y = c("y1", "y2", "y3"), g = unique(dat$group))
备注
从有两个 y2 的问题中更正输入。
set.seed(123)
dat <- data.frame(group=c(rep("a",10), rep("b",10), rep("c",10)),
x=rnorm(30), y1=rnorm(30), y2=rnorm(30), y3=rnorm(30))