名称 (x) <- 值中的 gam 函数错误:“名称”属性必须与向量长度相同

王嘉炜*_*王嘉炜 7 r date gam

我正在使用该mgcv包根据一些环境协变量对臭氧污染浓度进行建模。该模型采用以下形式:

model1 <- gam(O3 ~ s(X, Y, bs = "tp", k = 10) + wd + s(date, bs = "cc", k = 100) + district,
              data = mydata, family = gaussian(link ="log"),
              na.action = "na.omit", method = "REML")
Run Code Online (Sandbox Code Playgroud)

这是协变量的结构:

> str(mydata)
'data.frame': 7100 obs. of  286 variables:
 $ date            : Date, format: "2016-01-01" "2016-01-01" "2016-01-01" ...
 $ O3              : num  0.0141 0.0149 0.0102 0.0159 0.0186 ...
 $ district        : Factor w/ 10 levels "bc","bh","dl",..: 1 8 7 8 2 6 4 4 10 2 ...
 $ wd              : Factor w/ 16 levels "E","ENE","ESE",..: 13 13 13 13 13 2 9 9 11 13 ...
 $ X               : num  0.389 0.365 1 0.44 0.892 ...
 $ Y               : num  0.311 0.204 0.426 0.223 0.162 ...
Run Code Online (Sandbox Code Playgroud)

我被困在一个

R 中的错​​误:“名称”属性 [1] 的长度必须与向量 [0] 的长度相同。

我试图通过s(date, bs = "cc", k = 100)从公式中删除术语来找出问题所在,它可以很好地工作。日期字段似乎有问题。

我不确定如何解决这个问题。任何建议将不胜感激!

Rei*_*son 7

date变量不会自动转换为数字变量;你需要自己做这件事。我通常按​​如下方式处理此类信息

mydata <- transform(mydata, ndate = as.numeric(date),
                    nyear  = as.numeric(format(date, '%Y')),
                    nmonth = as.numeric(format(date, '%m')),
                    doy    = as.numeric(format(date, '%j')))
Run Code Online (Sandbox Code Playgroud)

然后我可以选择以多种方式对时间分量进行建模:

  1. 趋势基于ndatenyear与非环状花键,或
  2. 基于nmonth或的循环模式doy(对于一年中的某一天),或
  3. 趋势和循环模式的结合

从您的问题中不清楚您的数据是否仅限于一年。如果数据跨越多年,那么您不能只对ndate变量使用循环样条。您将需要一个非常复杂的标准样条(选项 1)或包括两个样条,一个用于年份之间的部分,一个用于年份内的部分(选项 3)。

如果您的数据超过多年,那么我会将模型设置为

O3 ~ s(X, Y, bs = "tp", k = 10) + wd + s(doy, bs = 'cc', k = 20) +
     s(ndate, bs = "tp", k = 50) + district
Run Code Online (Sandbox Code Playgroud)

或者也许s(nyear, .... )将足以代替s(ndate, .... ).

这种时间分量的分解很有用,因为与单个更复杂的平滑相比,通过两个简单的、估计良好的平滑通常可以更好地拟合序列。它还允许您测试年内和年间的影响。

如果您需要季节性周期随趋势变化,那么张量积会很有帮助:

O3 ~ s(X, Y, bs = "tp", k = 10) + wd +
     te(doy, ndate, bs = c('cc','tp'), k = c(20,50)) + district
Run Code Online (Sandbox Code Playgroud)

对于循环样条,您可能还想设置knots参数,特别是如果您的数据不完全跨越一年中的全部天数等。因为doy我会使用knots = list(doy = c(0.5, 366.5))这允许 12 月 31 日和 1 月 1 日具有略有不同的估计值。因为nmonth这更重要,否则 Dec 和 Jan 将获得相同的拟合值。我用:knots = list(nmonth = c(0.5, 12.5))

这里的想法是,112反映各月中旬和0.512.5的第一个和最后几个月,我们可能期望是相同的开头和结尾。