如何使用data.table在所有列组合上找到线性回归

问题描述

我正在尝试为每个可能的变量组合找到 iris 数据集组之间的线性回归。由于这是一个玩具示例,因此很容易对每个变量集分别进行线性回归并连接结果。但是,由于 data.table 具有大量列,因此很难找到所有组之间的线性回归。

library(data.table)
  dt = copy(iris)
  setDT(dt)[,.(model1 = lm(Sepal.Length ~ Petal.Width,.SD)$coeff[2],model2 = lm(Petal.Width ~ Sepal.Length,.SD)$coeff[2]),by = Species]
      Species    model1     model2
1:     setosa 0.9301727 0.08314444
2: versicolor 1.4263647 0.20935719
3:  virginica 0.6508306 0.12141646

  setDT(dt)[,.(model1 = lm(Sepal.Width ~ Petal.Length,model2 = lm(Petal.Length ~ Sepal.Width,by = Species]
      Species    model1    model2
1:     setosa 0.3878739 0.0814112
2: versicolor 0.3743068 0.8393782
3:  virginica 0.2343482 0.6863153

  setDT(dt)[,.(model1 = lm(Sepal.Width ~ Sepal.Length,model2 = lm(Sepal.Length ~ Sepal.Width,by = Species]
      Species    model1    model2
1:     setosa 0.7985283 0.6904897
2: versicolor 0.3197193 0.8650777
3:  virginica 0.2318905 0.9015345

  setDT(dt)[,.(model1 = lm(Petal.Width ~ Petal.Length,model2 = lm(Petal.Length ~ Petal.Width,by = Species]
      Species    model1    model2
1:     setosa 0.2012451 0.5464903
2: versicolor 0.3310536 1.8693247
3:  virginica 0.1602970 0.6472593

不是分别对每组变量进行线性回归,是否可以使用 data.table 轻松完成?我想要的输出如下-

      Species   Variable1   Variable2     model1     model2
       setosa Sepal.Length  Petal.Width   0.9301727 0.08314444
   versicolor Sepal.Length  Petal.Width   1.4263647 0.20935719
    virginica Sepal.Length  Petal.Width   0.6508306 0.12141646
       setosa Sepal.Width   Petal.Length  0.3878739 0.0814112
   versicolor Sepal.Width   Petal.Length  0.3743068 0.8393782
    virginica Sepal.Width   Petal.Length  0.2343482 0.6863153
       setosa Sepal.Width   Sepal.Length  0.7985283 0.6904897
   versicolor Sepal.Width   Sepal.Length  0.3197193 0.8650777
    virginica Sepal.Width   Sepal.Length  0.2318905 0.9015345
       setosa Petal.Width   Petal.Length  0.2012451 0.5464903
   versicolor Petal.Width   Petal.Length  0.3310536 1.8693247
    virginica Petal.Width   Petal.Length  0.1602970 0.6472593

解决方法

我们可以使用 combn 创建一个 list 的公式,在 'iris' 的列名('Species' 除外)上带有 reformulate,然后循环遍历 {{1} } 按数据中的“物种”分组,应用 list 并提取 lmicients

coeff

-输出

library(data.table)
lst1 <- combn(names(iris)[-5],2,FUN = 
      function(x) reformulate(x[1],x[2]),simplify = FALSE)
dt = copy(iris)
out <- setDT(dt)[,lapply(lst1,function(fmla) 
        lm(fmla,.SD)$coeff),by = Species]
setnames(out,-1,sapply(lst1,deparse))