将apply()与自定义函数和第二个数据框

时间:2017-07-07 22:34:33

标签: r apply

我正在尝试从大量的模型模拟中生成预测值,而我很难完成它。我怀疑我需要来自apply()系列的东西,但我无法弄清楚语法。也许我对apply()的了解很少。或许我的功能错了。有什么建议吗?

假设我有六个模型模拟产生的跟随系数......

coef <- data.frame(intercept=c(2,3,5,7,2,1),
                   b1 = c(.2,.5,.6,.7,.9,.4),
                   b2 = c(10,11,12,11,9,10))

我想计算(预测值或)上面每行和下一个数据帧的每一行的线性组合...

df <- data.frame(age = c(50,20,19, 42),
                 height = c(60,72,79, 66))

......使用以下模型方程式:

coef$intercept + coef$b1*df$age + coef$b2*df$height

如果做得对,我应该得到以下24个数据值:

612.0   726.0   795.8   670.4
688.0   805.0   881.5   750
755.0   881.0   964.4   822.2
702.0   813.0   889.3   762.4
587.0   668.0   730.1   633.8
621.0   729.0   798.6   677.8

为了实现上述目的,我尝试了以下功能并使用了apply()...

equation <-  function(...) coef$intercept + coef$b1*df$age + coef$b2*df$height
result <- apply(df, 1, equation)

...但我没有得到正确的答案。 “结果”数据框只重复正确的对角线。我也收到了消息:

> Warning messages: 1: In coef$b1 * df$age :   longer object length is
> not a multiple of shorter object length

是的,我可以通过简单的矩阵乘法得到正确的答案:

df$ones <- 1
df <- df[,c(3, 1, 2)]
result <- as.matrix(coef) %*% t(as.matrix(df))

但在我看来,应该能够更普遍地使用apply()和自定义函数来做到这一点。 apply()的使用更紧凑,使我的矩阵列的顺序错误的风险更小。有什么建议吗?

3 个答案:

答案 0 :(得分:3)

如果确实想要使用apply,您可以这样做:

result<- t(apply(coef, 1, function(x) x[1] + x[2]*df$age + x[3]*df$height))
> result
     [,1] [,2]  [,3]  [,4]
[1,]  612  726 795.8 670.4
[2,]  688  805 881.5 750.0
[3,]  755  881 964.4 822.2
[4,]  702  813 889.3 762.4
[5,]  587  668 730.1 633.8
[6,]  621  729 798.6 677.8

但是进行矩阵乘法确实更好(也更快)。

答案 1 :(得分:3)

我们可以使用%*%

执行此操作
coef[,1] + as.matrix(coef[-1]) %*% t(df)
#     [,1] [,2]  [,3]  [,4]
#[1,]  612  726 795.8 670.4
#[2,]  688  805 881.5 750.0
#[3,]  755  881 964.4 822.2
#[4,]  702  813 889.3 762.4
#[5,]  587  668 730.1 633.8
#[6,]  621  729 798.6 677.8

答案 2 :(得分:1)

这是我要做的:

sapply(seq_along(1:nrow(coef)), function(x){

  sapply(seq_along(1:nrow(df)), function(y) {
    coef$intercept[[x]] + coef$b1[[x]]*df$age[[y]] + coef$b2[[x]]*df$height[[y]]
  })

})

结果:

     [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
[1,] 612.0 688.0 755.0 702.0 587.0 621.0
[2,] 726.0 805.0 881.0 813.0 668.0 729.0
[3,] 795.8 881.5 964.4 889.3 730.1 798.6
[4,] 670.4 750.0 822.2 762.4 633.8 677.8

使用两个sapplys。每个对象一个(dfcoef)。