purrr::map_dbl(...) 使用 Michael Foley 的时间序列分析教程绘制 ETS 模型预测时出错

问题描述 投票:0回答:1

复制错误https://bookdown.org/mpfoley1973/time-series/ 加载库 运行 https://bookdown.org/mpfoley1973/time-series/exponential.html 第 4.1 节中的代码

purrr 中的 mutate 错误

map_dbl()
中的错误: 索引中:1。 错误原因: !结果长度必须为 1,而不是 0。`

仍然是 R 初学者,所以不知道如何调试问题。 搜索发现这篇文章purrr::map_dbl(...)错误 - 如何修复它?但是这篇文章没有足够的细节。

代码

library(tidyverse)
library(lubridate)
library(patchwork) #  arranging plots
library(glue)
library(tsibble)
library(feasts) # feature extraction and statistics
library(fable) # forecasting
library(tsibbledata)

 tsibbledata::global_economy %>%
   filter(Country == "Algeria") %>%
   ggplot(aes(x = Year, y = Exports)) +
   geom_line() +
   theme_light() +
   labs(title = "Algerian exports (% of GDP) show no trend or seasonality.")
 
 mdl_ses <- tsibbledata::global_economy %>%
   filter(Country == "Algeria") %>%
   model(ETS(Exports ~ error("A") + trend("N") + season("N")))
 
 mdl_ses %>% report()
 
 gg_tsresiduals(mdl_ses)
 
 mdl_ses_fc <- mdl_ses %>%
   forecast(h = 5) %>%
   mutate(sigma = map_dbl(Exports, ~pluck(.x, "sigma")),
          ci_025 = qnorm(.025, .mean, sigma),
          ci_975 = qnorm(.975, .mean, sigma))

time-series purrr
1个回答
0
投票

map() 崩溃,因为 pluck() 返回 NULL

pluck()
正在
"sigma"
列的每个索引中查找
Exports

在至少一些(可能是所有)实例中,

pluck()
找不到任何称为
"sigma"
的内容,因此返回
NULL
。当返回
map_dbl()
时,
NULL
会崩溃,因为
NULL
的长度为 0,而
map_dbl()
不喜欢长度为零的东西。

您可以通过使用

map()
而不是
map_dbl()
来解决此问题;这将返回
sigma
作为列表列,其中将包含一些
NULL
值。检查此列表列(以及这些行中
Exports
的值)将使您更好地了解为什么
"sigma"
中缺少
Exports

这是一个解释错误性质的最小示例:

library(purrr)

test <- list(
  list(foo = 1, bar = 2),
  list(foo = 3, bar = 4),
  list(foo = 5)           # 'bar' is missing here
)

## Plucking "foo" from the third element of `test`
## works just fine
pluck(test, 3, "foo")
#> [1] 5

## Plucking "bar" **also** works fine, but it returns 
## NULL (this is expected behaviour)
pluck(test, 3, "bar")
#> NULL

## When we look for 'foo', map_dbl() get's three numbers
## and combines them into a numerical vector

map_dbl(test, ~pluck(.x, "foo"))
#> [1] 1 3 5

## When we look for 'bar', map_dbl() gets two numbers and one
## instance of NULL. map_dbl() crashes, because that's how it
## responds to zero-length outputs.

map_dbl(test, ~pluck(.x, "bar"))
#> Error in `map_dbl()`:
#> ℹ In index: 3.
#> Caused by error:
#> ! Result must be length 1, not 0.
#> Backtrace:
#>     ▆
#>  1. ├─purrr::map_dbl(test, ~pluck(.x, "bar"))
#>  2. │ └─purrr:::map_("double", .x, .f, ..., .progress = .progress)
#>  3. │   ├─purrr:::with_indexed_errors(...)
#>  4. │   │ └─base::withCallingHandlers(...)
#>  5. │   └─purrr:::call_with_cleanup(...)
#>  6. └─base::.handleSimpleError(...)
#>  7.   └─purrr (local) h(simpleError(msg, call))
#>  8.     └─cli::cli_abort(...)
#>  9.       └─rlang::abort(...)

## Using map() instead of map_dbl() circumvents the
## error, since map() can just package the NULL
## up into a list-element:

output <- map(test, ~pluck(.x, "bar"))
output
#> [[1]]
#> [1] 2
#> 
#> [[2]]
#> [1] 4
#> 
#> [[3]]
#> NULL

创建于 2023-08-16,使用 reprex v2.0.2

此错误是设计使然:

map_*
函数系列始终返回与其输入长度相同的输出。长度为 3 的列表可以包含
NULL
值,但数值向量
c(2, 3, NULL)
相当于
c(2, 3)
并且长度为 2。因此,接受
NULL
输出可能会导致
map_dbl()
出现意外行为,即为什么函数会崩溃。


PS:也可能

Exports$sigma
不是
NULL
但长度仍然为零(例如
Exports <- list(foo = 10, sigma = numeric(0))
)。无论哪种情况,解决方案都是相同的。

© www.soinside.com 2019 - 2024. All rights reserved.