复制错误 从 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))
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))
)。无论哪种情况,解决方案都是相同的。