使用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) 

并在虹膜数据帧中为我提供了4C2(6)个附加变量,其中包含所有乘法变量。最后,我需要对一个包含70K obs和大约100个变量的数据帧执行此操作。提前感谢!

完全避免循环,使用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]] )

以下是我的操作方法:

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标识符是什么;您必须返回data

创建矢量的所有双向组合的方法是使用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  

相关内容

  • 没有找到相关文章

最新更新