使用 R 创建乘法交互变量

Creating multiplicative interaction variables using R

我正在尝试编写一个函数来计算我指定的变量的所有乘法交互作用。请参阅下面的代码以了解我正在尝试做什么。

mul <- function(data, vars)
{
for(ii in vars)
 {
  for(jj in vars[ii : length(vars)])
  {
   data[, paste(ii, jj, sep = "mul")] <- 
   data[,  which(colnames(data) %in%   ii)]*data[,   which(colnames(data) %in% jj)]
  }

 }
test   
}

由于我是 R 的业​​余爱好者,请一些 R 黑带编码员帮助我。

作为数据示例,我希望下面的代码最终能正常工作:

data(iris)
x <- names(iris)[1:4]
mul(iris, x) 

并在我的虹膜 data.frame 中为我提供了 4C2 (6) 个附加变量,其中包含所有乘法变量。最后,我需要为具有 70K obs 和 ~100 个变量的数据框执行此操作。提前致谢!

我会这样做:

data('iris');
head(iris);
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
mul <- function(data, cols ) {
    for (i in 1:(length(cols)-1)) {
        for (j in (i+1):length(cols)) {
            col1 <- cols[i];
            col2 <- cols[j];
            data[,paste(col1,col2,sep='.mul.')] <- data[,col1]*data[,col2];
        };
    };
    data;
};
iris.mul <- mul(iris, names(iris)[1:4] );
head(iris.mul);
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length.mul.Sepal.Width Sepal.Length.mul.Petal.Length Sepal.Length.mul.Petal.Width Sepal.Width.mul.Petal.Length Sepal.Width.mul.Petal.Width Petal.Length.mul.Petal.Width
## 1          5.1         3.5          1.4         0.2  setosa                        17.85                          7.14                         1.02                         4.90                        0.70                         0.28
## 2          4.9         3.0          1.4         0.2  setosa                        14.70                          6.86                         0.98                         4.20                        0.60                         0.28
## 3          4.7         3.2          1.3         0.2  setosa                        15.04                          6.11                         0.94                         4.16                        0.64                         0.26
## 4          4.6         3.1          1.5         0.2  setosa                        14.26                          6.90                         0.92                         4.65                        0.62                         0.30
## 5          5.0         3.6          1.4         0.2  setosa                        18.00                          7.00                         1.00                         5.04                        0.72                         0.28
## 6          5.4         3.9          1.7         0.4  setosa                        21.06                          9.18                         2.16                         6.63                        1.56                         0.68

备注:

  • 您在代码中对 ii 的使用不一致;您已将其设置为遍历每个列名(在 for (ii in vars) 中),但还试图将其用作 ii:length(vars) 表达式中的数字索引。我使用ij作为数字索引变量,然后在内部循环中分配col1col2
  • 为了避免重复,您必须在所有列 上迭代外循环,最后一列除外 ,然后在 的所有列上迭代内循环]一个在 当前外部迭代器之后一直到最后一个。因此,在我的代码中 i 超过 1:(length(cols)-1) 并且 j 超过 (i+1):length(cols).
  • 不确定函数末尾的 test 标识符是什么;你必须 return data.

完全避免循环,使用combn:

data(iris)
x <- names(iris)[1:4]
combn(x,2,FUN=function(x) iris[,x[1]] * iris[,x[2]]  )
#      [,1]  [,2]  [,3]  [,4] [,5]  [,6]
#[1,] 17.85  7.14  1.02  4.90 0.70  0.28
#[2,] 14.70  6.86  0.98  4.20 0.60  0.28
#[3,] 15.04  6.11  0.94  4.16 0.64  0.26
#[4,] 14.26  6.90  0.92  4.65 0.62  0.30
# etc etc

如果要同时设置名称,请执行:

iris[combn(x,2,FUN=paste0,collapse=".by.")] <- 
  combn(x,2,FUN=function(x) iris[,x[1]] * iris[,x[2]] )

创建向量的所有 2 种组合的方法是使用 combn:

> combn(x, 2)
     [,1]           [,2]           [,3]           [,4]          
[1,] "Sepal.Length" "Sepal.Length" "Sepal.Length" "Sepal.Width" 
[2,] "Sepal.Width"  "Petal.Length" "Petal.Width"  "Petal.Length"
     [,5]          [,6]          
[1,] "Sepal.Width" "Petal.Length"
[2,] "Petal.Width" "Petal.Width" 

然后您可以迭代该字符矩阵的列:

comb.names <- combn(x, 2)
for ( i in 2:ncol(comb.names) ){ test <- cbind(test,
    iris[[ comb.names[1,i] ]]*iris[[ comb.names[2,i] ]])
    names(test)[i] <- paste( substr(comb.names[1,i],1,7), 
                             substr( comb.names[2,i],1,7),sep="_")}
 str(test)
#--------------------
'data.frame':   150 obs. of  6 variables:
 $ SepL.SepW      : num  17.8 14.7 15 14.3 18 ...
 $ Sepal.L_Petal.L: num  7.14 6.86 6.11 6.9 7 9.18 6.44 7.5 6.16 7.35 ...
 $ Sepal.L_Petal.W: num  1.02 0.98 0.94 0.92 1 2.16 1.38 1 0.88 0.49 ...
 $ Sepal.W_Petal.L: num  4.9 4.2 4.16 4.65 5.04 6.63 4.76 5.1 4.06 4.65 ...
 $ Sepal.W_Petal.W: num  0.7 0.6 0.64 0.62 0.72 1.56 1.02 0.68 0.58 0.31 ...
 $ Petal.L_Petal.W: num  0.28 0.28 0.26 0.3 0.28 0.68 0.42 0.3 0.28 0.15 ...
#------------------

真正快速的方法...假设您正在考虑回归问题是使用 R 公式评估:

lm(as.numeric(Species) ~ (.)^2, data=iris)

Call:
lm(formula = as.numeric(Species) ~ (.)^2, data = iris)

Coefficients:
              (Intercept)               Sepal.Length  
                 4.425390                  -0.792828  
              Sepal.Width               Petal.Length  
                -1.119006                   0.228466  
              Petal.Width   Sepal.Length:Sepal.Width  
                 1.378179                   0.240113  
Sepal.Length:Petal.Length   Sepal.Length:Petal.Width  
                -0.004753                  -0.050226  
 Sepal.Width:Petal.Length    Sepal.Width:Petal.Width  
                -0.017482                  -0.356884  
 Petal.Length:Petal.Width  
                 0.135710