我正试图编写一个函数来计算我指定的变量的所有乘法交互作用。参考下面的代码来了解我正在尝试做什么。
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)
表达式中的数字索引。我使用i
和j
作为数字索引变量,然后在内部循环中分配col1
和col2
- 为了避免重复,您必须在所有列上迭代外循环,除了最后一列,然后在所有列上迭代内循环,从当前外部迭代器后面的一直到最后一列。因此,在我的代码中,
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