在 R 中,不能在包 Vignette 文件中编出相同的代码。“列表”对象不能被强制为整数类型

Sca*_*ett 6 vignette r function tsibble

这个问题是关于包 GRATIS 中的 generate_msts() 函数。

我添加了一些新东西(使函数可以选择将其输出转换为可爱的 tsibble 格式或保留原始的“列表”格式)并准备更新到 CRAN。

新代码添加如下(代码的详细信息以及问题底部显示的示例)

我想知道我应该得到 tsibble 索引吗?但是生成的数据好像没有索引?

  output <- if (output_format == "list") {
    res                                    #this is output name defined before
  } else if (output_format == "tsibble") {
    as_tsibble(res)
  }
  return(output)
}
Run Code Online (Sandbox Code Playgroud)

作为指导,我在Vignette 中更新了此函数的相应示例。然后事情变得连贯起来。

如果我没有保存生成的时间序列输出(例如 x <- my_function()),则小插图 无法编织。(不过我可以在独立的普通RMD文件中直接使用这个功能)

直接使用这段代码可以在RStudio里面显示输出,但是不能编出来。

my_function(seasonal.periods = c(7, 365), n = 800, nComp = 2,output_format="tsibble")
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

Error in Fun(X[[i]],...): 'list' object cannot be coerced to type 'integer' Calls: <Anonymous>... 
as.data.frame -> head  -> head.data.frame -> lappy -> FUN Execution halted.
Run Code Online (Sandbox Code Playgroud)

但是,这很好用。它可以编织小插图并显示tsibble的头部。

x <- my_function(seasonal.periods = c(7, 365), n = 800, nComp = 2,output_format="tsibble")
head(x)
Run Code Online (Sandbox Code Playgroud)

不过这样每次都先保存后才能使用,非常不方便。我想知道这是不是因为我在包中使用的任何默认设置或小插图没有改变?或者在更改 R 包中的函数后我需要做一些额外的步骤?或者甚至我添加的if else内容需要改进?

我试图devtools::document("C:/Users/mreal/Documents/GitHub/package_name");devtools::install("C:/Users/mreal/Documents/GitHub/package_name")更新重建功能。但这仍然无助于小插图。

我也试过rm(list=ls())console。它也不起作用

我在小插图中使用的代码如下

Github 链接:

https://github.com/BocongZhao823/gratis/blob/master/vignettes/QuickStart.Rmd

---
title: "Introduction to gratis"
author: "Bocong Zhao"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Introduction to gratis}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

{r initial, echo = FALSE, cache = FALSE, results = 'hide'}
library(knitr)
opts_chunk$set(
  warning = FALSE, message = FALSE, echo = TRUE,
  fig.width = 7, fig.height = 6, fig.align = 'centre',
  comment = "#>"
)
original <- options("tibble.print_min")
options(tibble.print_min = 5)
# <---- Do stuff with changed option, e.g. print some tibbles ----> 
options(tibble.print_min = original)


{r, message=FALSE, include = FALSE}
library(forecast)
library(tsibble)

{r setup}
# load package
library(gratis)

## Generate mutiple seasonal time series

Time series can exhibit multiple seasonal pattern of different length, especially when series observed at a high frequency such as daily or hourly data.

We use function **generate_msts()** to generate mutiple seasonal time series.

**Definitions**

Here are the definitions of parameter settings in function generate_msts():

|parameter settings | Definition|
|:----|:-----|
|seasonal.periods | a vector of seasonal periods of the time series to be generated|
|nComp|number of mixing components when simulating time series using MAR models|
|n    |length of the generated time series|

**Example**

Suppose we want to use MAR model to generate a time series with **2** mixing components and the length **800** from random parameter spaces. Particularly, this time series has two seasonal periods **7** and **365**.

{r fig.height = 6, fig.width = 7}
# Generate mutiple seasonal time series with 'tsibble' output format
x <- generate_msts(seasonal.periods = c(7, 365), n = 800, nComp = 2,output_format="tsibble")
head(x)

**Plot time series**

{r fig.height = 6, fig.width = 7}
# Generate mutiple seasonal time series with 'list' output format
x <- generate_msts(seasonal.periods = c(7, 365), n = 800, nComp = 2,output_format="list")
autoplot(x)
Run Code Online (Sandbox Code Playgroud)

(生成的.R文件)包内使用的R代码如下

** Github 链接**

https://github.com/BocongZhao823/gratis/blob/master/R/generate_ts.R

#' Generate mutiple seasonal time series from random parameter spaces of the mixture autoregressive (MAR) models.
#'
#' Generate mutiple seasonal time series from random parameter spaces of the mixture autoregressive (MAR) models.
#' @param seasonal.periods a vector of seasonal periods of the time series to be generated.
#' @param n length of the generated time series.
#' @param nComp number of mixing components when simulating time series using MAR models.
#' @param output_format An optional argument which allows to choose output format between "list" and "tsibble"
#' @return a time series with multiple seasonal periods.
#' @export
#' @examples
#' x <- generate_msts(seasonal.periods = c(7, 365), n = 800, nComp = 2, output_format= "list")
#' forecast::autoplot(x)
generate_msts <- function(seasonal.periods = c(7, 365), n = 800, nComp = NULL,output_format="list") {
  x.list <- map(seasonal.periods, function(p) {
    generate_ts(n.ts = 1, freq = p, n = n, nComp = nComp)$N1$x
  })
  names(x.list) <- paste0("Season", seasonal.periods)
  x.list[1:(length(x.list) - 1)] <- lapply(x.list[1:(length(x.list) - 1)], function(x) {
    x - trendcycle(stl(x, "per"))
  })
  weights <- msts_weights(length(seasonal.periods))
  res <- as_tibble(scale(x.list %>% bind_cols())[, ]) %>%
    mapply("*", ., weights) %>%
    as_tibble() %>%
    mutate(x = rowSums(.)) %>%
    select(x) %>%
    msts(seasonal.periods = seasonal.periods)
  # New content
  output <- if (output_format == "list") {
    res
  } else if (output_format == "tsibble") {
    as_tsibble(res)
  }
  return(output)
}

# ===========================================================================
# Simulated weights for the simulation of msts
# ===========================================================================
msts_weights <- function(n.periods) {
  gamma <- runif(n.periods, 0)
  weights <- gamma / sum(gamma)
  return(weights)
}
Run Code Online (Sandbox Code Playgroud)

sta*_*007 1

我尝试为你运行这个 - 我的第一个猜测是命名空间问题。不过好像也和generate_msts()功能有关。

\n

我真的不认为这与首先将其保存到变量有关x

\n

以下是我的发现:

\n

不起作用:

\n
x <- generate_msts(seasonal.periods = c(7, 365), n = 800, nComp = 2,output_format="tsibble")\n\nx\n
Run Code Online (Sandbox Code Playgroud)\n

不起作用:

\n
print(generate_msts(seasonal.periods = c(7, 365), n = 800, nComp = 2,output_format="tsibble"))\n
Run Code Online (Sandbox Code Playgroud)\n

不起作用:

\n
x <- generate_msts(seasonal.periods = c(7, 365), n = 800, nComp = 2,output_format="tsibble")\n\nprint(x)\n
Run Code Online (Sandbox Code Playgroud)\n

作品:

\n
 head(generate_msts(seasonal.periods = c(7, 365), n = 800, nComp = 2,output_format="tsibble"))\n
Run Code Online (Sandbox Code Playgroud)\n

在失败的情况下,它总是与您相同的错误消息:

\n
\n

错误:处理小插图“QuickStart.Rmd”失败并诊断:\n“list”对象无法强制键入“integer”

\n
\n

因此,由于head(), str(),class()总是对我有用,只是print()不起作用,我假设这是打印功能的问题。因此,将其保存到变量中的解决方法效果x很好,因为您没有调用打印函数。

\n

同样重要的是,这个问题只发生在我在内部使用generate_msts()时Rmarkdown。正如我稍后解释的那样,这似乎是合理的,因为在knitr中打印与在控制台上打印不同。

\n

当我改变你的generate_msts()并重建包时:

\n
output <- if (output_format == "list") {\n    res\n  } else if (output_format == "tsibble") {\n    tsibble(date = as.Date("2017-01-01") + 0:9,value = rnorm(10))\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

Rmarkdown 突然运行没有错误。

\n

我的猜测是,与knitr交互时特定数据的print()存在问题。

\n

在knitr中打印似乎与在控制​​台上打印不同(可能是它在没有rmarkdown的情况下工作的原因)

\n

这是关于自定义打印方法和 knitr 的好链接:\n https://cran.r-project.org/web/packages/knitr/vignettes/knit_print.html

\n
\n

在 knit v1.6 之前,在 R 代码块中打印对象基本上是模拟 R 控制台。

\n
\n

我可以想象 tsibble 包中 knit_print 的 S3 方法(它只使用 tibble 中的所有打印方法?)可能无法正常工作于您的特定数据集(我的意思是它适用于我使用 tsibble 创建的 tsibble tsibble())。但只是一个(疯狂的?)猜测......总体上的错误和行为真的很奇怪......

\n

编辑:\n这也是错误的 R Markdown 调用堆栈:

\n
 1. \xe2\x94\x9c\xe2\x94\x80base::print(x)\n  2. \xe2\x94\x94\xe2\x94\x80tibble:::print.tbl(x)\n  3.   \xe2\x94\x9c\xe2\x94\x80cli::cat_line(format(x, ..., n = n, width = width, n_extra = n_extra))\n  4.   \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80base::paste0(..., collapse = "\\n")\n  5.   \xe2\x94\x9c\xe2\x94\x80base::format(x, ..., n = n, width = width, n_extra = n_extra)\n  6.   \xe2\x94\x94\xe2\x94\x80tsibble:::format.tbl_ts(x, ..., n = n, width = width, n_extra = n_extra)\n  7.     \xe2\x94\x9c\xe2\x94\x80base::format(trunc_mat(x, n = n, width = width, n_extra = n_extra))\n  8.     \xe2\x94\x94\xe2\x94\x80tibble::trunc_mat(x, n = n, width = width, n_extra = n_extra)\n  9.       \xe2\x94\x9c\xe2\x94\x80base::as.data.frame(head(x, n))\n 10.       \xe2\x94\x9c\xe2\x94\x80utils::head(x, n)\n 11.       \xe2\x94\x94\xe2\x94\x80utils:::head.data.frame(x, n)\n 12.         \xe2\x94\x94\xe2\x94\x80base::lapply(...)\n 13.           \xe2\x94\x94\xe2\x94\x80utils:::FUN(X[[i]], ...)\n
Run Code Online (Sandbox Code Playgroud)\n

对你来说应该是类似的,但是如果你想自己得到这个,你必须在你的 rmarkdown 文档中使用以下命令

\n
options(rlang_trace_top_env = rlang::current_env())\noptions(error = function() {\n  sink()\n  print(rlang::trace_back(bottom = sys.frame(-1)), simplify = "none")\n})\n
Run Code Online (Sandbox Code Playgroud)\n

但正如你在调用堆栈中看到的,错误是由base::print(x)引起的,它调用了S3方法tibble:::print.tbl(x),该方法然后在内部调用了tsibble:::format.tbl_ts ,它调用 tibble::trunc_mat, ...并且在内部某处导致了错误。

\n

好吧...我继续沿着这条路走下去...这些函数调用中最终混乱的是您在开始时设置的 knitr 选项。

\n

您在 rmarkdown 的开头写道:

\n
original <- options("tibble.print_min")\noptions(tibble.print_min = 5)\n\n# <---- Do stuff with changed option, e.g. print some tibbles ----> \noptions(tibble.print_min = original)\n
Run Code Online (Sandbox Code Playgroud)\n

将其更改为:

\n
options(tibble.print_min = 5)\n
Run Code Online (Sandbox Code Playgroud)\n

那时应该工作。

\n

  • 可能是,你有点混淆了...... tsibble 基本上就是一个 tibble。正如您在 tsibble 对象上调用 class() 时所看到的。因此,当您打印 tsibble 时,它​​会自动调用 print.tbl。 (2认同)