r回归模型中的元组变量

时间:2018-08-16 09:56:13

标签: r regression

我正在尝试将“每日时间”用作模型中的自变量。由于时间是一个循环变量,因此我将其转换为(sin(pi * hour / 12),cos(pi * hour / 12))。

我四处搜寻,但我仍然不知道如何用(sin,cos)格式的向量/元组值在R中创建列。我不知道lm,glm,glm.nb(MASS)和glmer(lme4)模型是否可以支持此类数据。

不好意思,我是这里的新手。如果向量类型变量不应该包含在回归模型中,那么我将去交叉验证(统计)以获取有关处理循环变量的建议。请帮助并分享您的经验,谢谢!

1 个答案:

答案 0 :(得分:0)

这是一个很好的问题。

在内部,R使用矩阵将模型拟合到数据中。您不必生成模型作为元组的函数,而需要生成一个块矩阵;例如,这就是样条线的实现方式。

在您的示例中,一列包含sin(x),另一列cox(x),并且这些块用class属性标记;内部管理此对象的功能是makepredictcallpredict

任何使用标准model.frame / model.matrix处理的模型都应与此兼容。

sincos <- function(x, period=168/2/pi) {
  structure(cbind(`_sin`=sin(x/period), 
                  `_cos`=cos(x/period)),
            class="sincos", 
            period=period)
}

在这里,我们将类别和句点设置为属性。

makepredictcall.sincos <- function(var, call){
  if (as.character(call)[1L] != "sincos")
    return(call)
  call["period"] <- attr(var, "period")
  call
}

根据需要在通话中设置时间段。

predict.sincos <- function(object, newx, ...)
{
  if(missing(newx))
    return(object)
  sincos(newx, period=attr(object, "period"))
}

使用来自拟合模型的时间段调用我们的函数。

以下是使用lm的简短示例:

#FAKE DATA EXAMPLE
N <- 1000
hr <- sample(168, N, replace = TRUE)
Y = 5 + sinpi(hr * 2/168) + cospi(hr * 2/168) + rnorm(N)

lm(Y~sinpi(hr*2/168)+cospi(hr*2/168))
#> 
#> Call:
#> lm(formula = Y ~ sinpi(hr * 2/168) + cospi(hr * 2/168))
#> 
#> Coefficients:
#>       (Intercept)  sinpi(hr * 2/168)  cospi(hr * 2/168)  
#>            5.0078             1.0243             0.9637

我们的自定义函数完全匹配:

lm(Y~sincos(hr))
#> 
#> Call:
#> lm(formula = Y ~ sincos(hr))
#> 
#> Coefficients:
#>    (Intercept)  sincos(hr)_sin  sincos(hr)_cos  
#>         5.0078          1.0243          0.9637

其他函数也将能够看出这两列是模型中的单个术语:

anova(lm(Y~sincos(hr)))
#> Analysis of Variance Table
#> 
#> Response: Y
#>             Df  Sum Sq Mean Sq F value    Pr(>F)    
#> sincos(hr)   2 1051.05  525.53  553.24 < 2.2e-16 ***
#> Residuals  997  947.06    0.95                      
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

如果其他人觉得有帮助,我会在接下来的几天内将其添加到stackoverflow包中。