乘以R中的向量标识的变量

时间:2018-03-07 16:21:13

标签: r apply

我需要手动为6 * 3变量创建交互项。我已将这些变量的名称存储到两个向量中,让我们将它们称为a和b。我们来调用我的数据帧df。

a <- c("var1","var2","var3")
b <- c("varA","varB","varC","varD","varE","varF")

我可以手动创建18个不同的变量,如:

df$var1.A <- df$var1*df$varA
df$var1.B <- df$var1*df$varB
df$var2.A <- df$var2*df$varA  
df$var2.B <- df$var2*df$varB

依此类推,但这显然不够优雅且容易出错。我曾尝试使用apply,sapply等,但尚未找到解决方案。

更新

感谢@akrun带着他的回答让我走上了正确的道路。但是,我现在需要计算另一组交互,这次使用&#39; transform&#39;,所以基本语法将是

df <- transform(df, var1.A = var1*varA)
df <- transform(df, var2.A = var2*varA)
df <- transform(df, var1.B = var1*varB)
df <- transform(df, var2.B = var1*varB)

等等其他17个互动。我试图调整提供给此任务的代码@akrun,但还没有成功。

我需要计算这些交互项的原因是我正在使用Amelia来增加错误数据的计算。由于交互将在我的分析中进行,我需要在估算缺失值时包含它们,而Amelia不会自动为我做这些。所以我计算了18个交互项,并让Amelia生成了一些插补数据集。然而,推算的互动术语并不一定与其组成术语一致,后者也缺少Amelia推测的数据。因此,为了运行我的分析,我需要根据完整值和估算值计算新的交互项。 Amelia的开发人员建议通过&#39; transform&#39;来实现这一点,如果应用于整个Amelia对象,则可以在所有的估算中使用。我无法用格式&#39; df $ var1.A&lt; - df $ var1 * df $ varA&#39;来实现同样的效果,这是我提问的最初主题,因此更新。

结束更新

有人可以帮忙吗?

任何同时将正确值分配给函数中正确位置的解决方案,并创建一个名称,该名称折叠由&#34;分隔的乘法变量的名称。&#34;非常感谢。

非常感谢提前!

3 个答案:

答案 0 :(得分:3)

我们可以通过在expand.grid

上执行vector来实现这一切
ab <- expand.grid(a, b, stringsAsFactors = FALSE)

根据扩展的向量组合

创建新的列名
nm1 <- sub("\\.var", ".", do.call(paste, c(ab, sep=".")))  

然后遍历每一行,对列进行子集化,乘以并分配输出以创建新列

df[nm1] <- apply(ab , 1, FUN = function(x) Reduce(`*`, df[x]))
df
#var1 var2 var3 varA varB varC varD varE varF var1.A var2.A var3.A var1.B var2.B var3.B var1.C var2.C var3.C var1.D var2.D var3.D var1.E var2.E var3.E var1.F
#1    3    9    6    9    1    7    3    2    5     27     81     54      3      9      6     21     63     42      9     27     18      6     18     12     15
#2    3    3    4    2    5    1    3    7    4      6      6      8     15     15     20      3      3      4      9      9     12     21     21     28     12
#3    7    7    7    1    7    6    4    6    3      7      7      7     49     49     49     42     42     42     28     28     28     42     42     42     21
#4    5    8    7    5    2    6    2    7    2     25     40     35     10     16     14     30     48     42     10     16     14     35     56     49     10
#5    6    3    3    2    3    1    9    9    1     12      6      6     18      9      9      6      3      3     54     27     27     54     27     27      6
#  var2.F var3.F
#1     45     30
#2     12     16
#3     21     21
#4     16     14
#5      3      3

数据

set.seed(24)
df <- as.data.frame(matrix(sample(1:9, 5 * 9, replace = TRUE), 
         5, 9, dimnames = list(NULL, c(a, b))))

答案 1 :(得分:2)

如果y是你的响应变量,那么运行你的线性模型:

lm(y ~ (var1 + var2 + var3) * (varA + varB + varC + varD + varE + varF), df)

这将给出第一组和第二组之间的拦截,主要效果和交互,但不在每组内(这是我对你想要的理解)。

如果想要使用ab,那么:

fo <- sprintf("y ~ (%s) * (%s)", paste(a, collapse = "+"), paste(b, collapse = "+"))
lm(fo, df)

例如,使用内置的anscombe data.frame:

lm(y1 ~ (y2 + y3) * (x1 + x2 + x3 + x4), anscombe)

给出:

Call:
lm(formula = y1 ~ (y2 + y3) * (x1 + x2 + x3 + x4), data = anscombe)

Coefficients:
(Intercept)           y2           y3           x1           x2           x3  
   259.9304       8.6943     -47.1185     -25.9360           NA           NA  
         x4        y2:x1        y2:x2        y2:x3        y2:x4        y3:x1  
    -0.2124       0.1627           NA           NA           NA       3.5765  
      y3:x2        y3:x3        y3:x4  
         NA           NA           NA  

答案 2 :(得分:0)

轻松

setNames(merge(a, b), c("col1", "col2"))