From ca54b63aa9abfcdb401d9f32ea91ea6d30567192 Mon Sep 17 00:00:00 2001 From: terrytangyuan Date: Sat, 19 Dec 2020 21:05:21 -0500 Subject: [PATCH] Revert "Clean up" This reverts commit fea710724d18ff6e70167043fe4787a834d95d27. --- CONDUCT.md | 43 ++ CONTRIBUTING.md | 40 ++ DESCRIPTION | 72 +++ ISSUE_TEMPLATE.md | 24 + NAMESPACE | 151 +++++++ NEWS.md | 94 ++++ R/base_fortify_list.R | 105 +++++ R/base_fortify_ts.R | 519 ++++++++++++++++++++++ R/fortify_MSwM.R | 76 ++++ R/fortify_base.R | 143 ++++++ R/fortify_basis.R | 96 ++++ R/fortify_changepoint.R | 129 ++++++ R/fortify_cluster.R | 165 +++++++ R/fortify_forecast.R | 150 +++++++ R/fortify_glmnet.R | 175 ++++++++ R/fortify_maps.R | 68 +++ R/fortify_performance.R | 114 +++++ R/fortify_raster.R | 101 +++++ R/fortify_spatial.R | 162 +++++++ R/fortify_stats.R | 447 +++++++++++++++++++ R/fortify_stats_density.R | 91 ++++ R/fortify_stats_lm.R | 335 ++++++++++++++ R/fortify_surv.R | 347 +++++++++++++++ R/fortify_vars.R | 97 ++++ R/geom.R | 35 ++ R/ggfortify.R | 13 + R/plotlib.R | 631 ++++++++++++++++++++++++++ R/tslib.R | 377 ++++++++++++++++ R/util.R | 120 +++++ README.rst | 143 ++++++ cran-comments.md | 16 + ggfortify.Rproj | 21 + inst/CITATION | 20 + man/apply_facets.Rd | 37 ++ man/apply_grid.Rd | 20 + man/as_tibble.basis.Rd | 39 ++ man/autoplot.MSM.lm.Rd | 33 ++ man/autoplot.RasterCommon.Rd | 52 +++ man/autoplot.SpatialCommon.Rd | 67 +++ man/autoplot.aareg.Rd | 44 ++ man/autoplot.acf.Rd | 77 ++++ man/autoplot.basis.Rd | 35 ++ man/autoplot.breakpoints.Rd | 39 ++ man/autoplot.cpt.Rd | 37 ++ man/autoplot.cv.glmnet.Rd | 88 ++++ man/autoplot.density.Rd | 62 +++ man/autoplot.forecast.Rd | 75 ++++ man/autoplot.ggmultiplot.Rd | 21 + man/autoplot.ggplot.Rd | 21 + man/autoplot.glmnet.Rd | 85 ++++ man/autoplot.kmeans.Rd | 31 ++ man/autoplot.list.Rd | 27 ++ man/autoplot.lm.Rd | 113 +++++ man/autoplot.map.Rd | 70 +++ man/autoplot.matrix.Rd | 109 +++++ man/autoplot.pca_common.Rd | 64 +++ man/autoplot.performance.Rd | 26 ++ man/autoplot.silhouette.Rd | 46 ++ man/autoplot.spec.Rd | 47 ++ man/autoplot.stepfun.Rd | 64 +++ man/autoplot.survfit.Rd | 127 ++++++ man/autoplot.ts.Rd | 142 ++++++ man/autoplot.tsmodel.Rd | 111 +++++ man/autoplot.varprd.Rd | 74 ++++ man/cbind_wraps.Rd | 22 + man/check_names.Rd | 19 + man/confint.acf.Rd | 26 ++ man/deprecate.warning.Rd | 19 + man/fitted.ar.Rd | 22 + man/flatten.Rd | 14 + man/fortify.MSM.lm.Rd | 31 ++ man/fortify.RasterCommon.Rd | 25 ++ man/fortify.SpatialCommon.Rd | 23 + man/fortify.aareg.Rd | 39 ++ man/fortify.acf.Rd | 41 ++ man/fortify.basis.Rd | 36 ++ man/fortify.cpt.Rd | 38 ++ man/fortify.cv.glmnet.Rd | 24 + man/fortify.density.Rd | 24 + man/fortify.dist.Rd | 24 + man/fortify.ets.Rd | 27 ++ man/fortify.factanal.Rd | 26 ++ man/fortify.forecast.Rd | 32 ++ man/fortify.glmnet.Rd | 24 + man/fortify.kmeans.Rd | 28 ++ man/fortify.lfda.Rd | 27 ++ man/fortify.list.Rd | 21 + man/fortify.matrix.Rd | 28 ++ man/fortify.performance.Rd | 21 + man/fortify.prcomp.Rd | 29 ++ man/fortify.silhouette.Rd | 29 ++ man/fortify.spec.Rd | 26 ++ man/fortify.stepfun.Rd | 27 ++ man/fortify.survfit.Rd | 33 ++ man/fortify.table.Rd | 24 + man/fortify.ts.Rd | 51 +++ man/fortify.tsmodel.Rd | 56 +++ man/fortify.varprd.Rd | 40 ++ man/fortify_base.Rd | 21 + man/fortify_map.Rd | 21 + man/geom_confint.Rd | 31 ++ man/geom_factory.Rd | 21 + man/get.dtindex.Rd | 28 ++ man/get.dtindex.continuous.Rd | 28 ++ man/get.layout.Rd | 24 + man/get_geom_function.Rd | 23 + man/ggbiplot.Rd | 161 +++++++ man/ggcpgram.Rd | 46 ++ man/ggdistribution.Rd | 47 ++ man/ggfortify.Rd | 9 + man/ggfreqplot.Rd | 57 +++ man/ggmultiplot-class.Rd | 48 ++ man/ggtsdiag.Rd | 58 +++ man/grid.draw.ggmultiplot.Rd | 16 + man/infer.Rd | 17 + man/is.univariate.Rd | 22 + man/is_derived_from.Rd | 22 + man/plot_confint.Rd | 54 +++ man/plot_label.Rd | 67 +++ man/plus-ggmultiplot-ANY-method.Rd | 19 + man/post_autoplot.Rd | 45 ++ man/post_fortify.Rd | 19 + man/print-ggmultiplot-method.Rd | 14 + man/rbind_ts.Rd | 35 ++ man/residuals.ar.Rd | 22 + man/show-ggmultiplot-method.Rd | 14 + man/support_autoplot.Rd | 17 + man/unscale.Rd | 25 ++ tests/test-all.R | 5 + tests/testthat/test-MSwM.R | 20 + tests/testthat/test-backcompat.R | 6 + tests/testthat/test-base-infer.R | 136 ++++++ tests/testthat/test-base.R | 60 +++ tests/testthat/test-base_ts.R | 16 + tests/testthat/test-basis.R | 26 ++ tests/testthat/test-changepoint.R | 82 ++++ tests/testthat/test-cluster.R | 185 ++++++++ tests/testthat/test-forecast.R | 183 ++++++++ tests/testthat/test-glmnet.R | 62 +++ tests/testthat/test-maps.R | 69 +++ tests/testthat/test-performance.R | 114 +++++ tests/testthat/test-plotlib.R | 233 ++++++++++ tests/testthat/test-raster.R | 144 ++++++ tests/testthat/test-spatial.R | 468 ++++++++++++++++++++ tests/testthat/test-stats-density.R | 25 ++ tests/testthat/test-stats-lm.R | 579 ++++++++++++++++++++++++ tests/testthat/test-stats.R | 657 ++++++++++++++++++++++++++++ tests/testthat/test-surv.R | 251 +++++++++++ tests/testthat/test-ts.R | 196 +++++++++ tests/testthat/test-tslib.R | 101 +++++ tests/testthat/test-util.R | 42 ++ tests/testthat/test-vars.R | 54 +++ tests/testthat/test_lint.R | 29 ++ vignettes/basics.Rmd | 165 +++++++ vignettes/plot_dist.Rmd | 45 ++ vignettes/plot_lm.Rmd | 84 ++++ vignettes/plot_map.Rmd | 109 +++++ vignettes/plot_pca.Rmd | 182 ++++++++ vignettes/plot_surv.Rmd | 43 ++ vignettes/plot_ts.Rmd | 275 ++++++++++++ 160 files changed, 13656 insertions(+) create mode 100644 CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 DESCRIPTION create mode 100644 ISSUE_TEMPLATE.md create mode 100644 NAMESPACE create mode 100644 NEWS.md create mode 100644 R/base_fortify_list.R create mode 100644 R/base_fortify_ts.R create mode 100644 R/fortify_MSwM.R create mode 100644 R/fortify_base.R create mode 100644 R/fortify_basis.R create mode 100644 R/fortify_changepoint.R create mode 100644 R/fortify_cluster.R create mode 100644 R/fortify_forecast.R create mode 100644 R/fortify_glmnet.R create mode 100644 R/fortify_maps.R create mode 100644 R/fortify_performance.R create mode 100644 R/fortify_raster.R create mode 100644 R/fortify_spatial.R create mode 100644 R/fortify_stats.R create mode 100644 R/fortify_stats_density.R create mode 100644 R/fortify_stats_lm.R create mode 100644 R/fortify_surv.R create mode 100644 R/fortify_vars.R create mode 100644 R/geom.R create mode 100644 R/ggfortify.R create mode 100644 R/plotlib.R create mode 100644 R/tslib.R create mode 100644 R/util.R create mode 100644 README.rst create mode 100644 cran-comments.md create mode 100644 ggfortify.Rproj create mode 100644 inst/CITATION create mode 100644 man/apply_facets.Rd create mode 100644 man/apply_grid.Rd create mode 100644 man/as_tibble.basis.Rd create mode 100644 man/autoplot.MSM.lm.Rd create mode 100644 man/autoplot.RasterCommon.Rd create mode 100644 man/autoplot.SpatialCommon.Rd create mode 100644 man/autoplot.aareg.Rd create mode 100644 man/autoplot.acf.Rd create mode 100644 man/autoplot.basis.Rd create mode 100644 man/autoplot.breakpoints.Rd create mode 100644 man/autoplot.cpt.Rd create mode 100644 man/autoplot.cv.glmnet.Rd create mode 100644 man/autoplot.density.Rd create mode 100644 man/autoplot.forecast.Rd create mode 100644 man/autoplot.ggmultiplot.Rd create mode 100644 man/autoplot.ggplot.Rd create mode 100644 man/autoplot.glmnet.Rd create mode 100644 man/autoplot.kmeans.Rd create mode 100644 man/autoplot.list.Rd create mode 100644 man/autoplot.lm.Rd create mode 100644 man/autoplot.map.Rd create mode 100644 man/autoplot.matrix.Rd create mode 100644 man/autoplot.pca_common.Rd create mode 100644 man/autoplot.performance.Rd create mode 100644 man/autoplot.silhouette.Rd create mode 100644 man/autoplot.spec.Rd create mode 100644 man/autoplot.stepfun.Rd create mode 100644 man/autoplot.survfit.Rd create mode 100644 man/autoplot.ts.Rd create mode 100644 man/autoplot.tsmodel.Rd create mode 100644 man/autoplot.varprd.Rd create mode 100644 man/cbind_wraps.Rd create mode 100644 man/check_names.Rd create mode 100644 man/confint.acf.Rd create mode 100644 man/deprecate.warning.Rd create mode 100644 man/fitted.ar.Rd create mode 100644 man/flatten.Rd create mode 100644 man/fortify.MSM.lm.Rd create mode 100644 man/fortify.RasterCommon.Rd create mode 100644 man/fortify.SpatialCommon.Rd create mode 100644 man/fortify.aareg.Rd create mode 100644 man/fortify.acf.Rd create mode 100644 man/fortify.basis.Rd create mode 100644 man/fortify.cpt.Rd create mode 100644 man/fortify.cv.glmnet.Rd create mode 100644 man/fortify.density.Rd create mode 100644 man/fortify.dist.Rd create mode 100644 man/fortify.ets.Rd create mode 100644 man/fortify.factanal.Rd create mode 100644 man/fortify.forecast.Rd create mode 100644 man/fortify.glmnet.Rd create mode 100644 man/fortify.kmeans.Rd create mode 100644 man/fortify.lfda.Rd create mode 100644 man/fortify.list.Rd create mode 100644 man/fortify.matrix.Rd create mode 100644 man/fortify.performance.Rd create mode 100644 man/fortify.prcomp.Rd create mode 100644 man/fortify.silhouette.Rd create mode 100644 man/fortify.spec.Rd create mode 100644 man/fortify.stepfun.Rd create mode 100644 man/fortify.survfit.Rd create mode 100644 man/fortify.table.Rd create mode 100644 man/fortify.ts.Rd create mode 100644 man/fortify.tsmodel.Rd create mode 100644 man/fortify.varprd.Rd create mode 100644 man/fortify_base.Rd create mode 100644 man/fortify_map.Rd create mode 100644 man/geom_confint.Rd create mode 100644 man/geom_factory.Rd create mode 100644 man/get.dtindex.Rd create mode 100644 man/get.dtindex.continuous.Rd create mode 100644 man/get.layout.Rd create mode 100644 man/get_geom_function.Rd create mode 100644 man/ggbiplot.Rd create mode 100644 man/ggcpgram.Rd create mode 100644 man/ggdistribution.Rd create mode 100644 man/ggfortify.Rd create mode 100644 man/ggfreqplot.Rd create mode 100644 man/ggmultiplot-class.Rd create mode 100644 man/ggtsdiag.Rd create mode 100644 man/grid.draw.ggmultiplot.Rd create mode 100644 man/infer.Rd create mode 100644 man/is.univariate.Rd create mode 100644 man/is_derived_from.Rd create mode 100644 man/plot_confint.Rd create mode 100644 man/plot_label.Rd create mode 100644 man/plus-ggmultiplot-ANY-method.Rd create mode 100644 man/post_autoplot.Rd create mode 100644 man/post_fortify.Rd create mode 100644 man/print-ggmultiplot-method.Rd create mode 100644 man/rbind_ts.Rd create mode 100644 man/residuals.ar.Rd create mode 100644 man/show-ggmultiplot-method.Rd create mode 100644 man/support_autoplot.Rd create mode 100644 man/unscale.Rd create mode 100644 tests/test-all.R create mode 100644 tests/testthat/test-MSwM.R create mode 100644 tests/testthat/test-backcompat.R create mode 100644 tests/testthat/test-base-infer.R create mode 100644 tests/testthat/test-base.R create mode 100644 tests/testthat/test-base_ts.R create mode 100644 tests/testthat/test-basis.R create mode 100644 tests/testthat/test-changepoint.R create mode 100644 tests/testthat/test-cluster.R create mode 100644 tests/testthat/test-forecast.R create mode 100644 tests/testthat/test-glmnet.R create mode 100644 tests/testthat/test-maps.R create mode 100644 tests/testthat/test-performance.R create mode 100644 tests/testthat/test-plotlib.R create mode 100644 tests/testthat/test-raster.R create mode 100644 tests/testthat/test-spatial.R create mode 100644 tests/testthat/test-stats-density.R create mode 100644 tests/testthat/test-stats-lm.R create mode 100644 tests/testthat/test-stats.R create mode 100644 tests/testthat/test-surv.R create mode 100644 tests/testthat/test-ts.R create mode 100644 tests/testthat/test-tslib.R create mode 100644 tests/testthat/test-util.R create mode 100644 tests/testthat/test-vars.R create mode 100644 tests/testthat/test_lint.R create mode 100644 vignettes/basics.Rmd create mode 100644 vignettes/plot_dist.Rmd create mode 100644 vignettes/plot_lm.Rmd create mode 100644 vignettes/plot_map.Rmd create mode 100644 vignettes/plot_pca.Rmd create mode 100644 vignettes/plot_surv.Rmd create mode 100644 vignettes/plot_ts.Rmd diff --git a/CONDUCT.md b/CONDUCT.md new file mode 100644 index 0000000..d9c56b6 --- /dev/null +++ b/CONDUCT.md @@ -0,0 +1,43 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +**Examples of behavior that contributes to creating a positive environment include:** + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +**Examples of unacceptable behavior by participants include:** + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at terrytangyuan@gmail.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..edd9011 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,40 @@ +# Contributing guidelines + +## How to become a contributor and submit your own code + +### Contributing code + +Make sure you understand how the code base is organized before you contribute any code. Check out our [R Journal paper](https://journal.r-project.org/archive/2016-2/tang-horikoshi-li.pdf) for more details on the architecture. Basically, if you want to extend the functionalities to more classes, you need to implement the following S3 generic functions for the classes you want to support: + +* `autoplot()`, which enables plotting a custom object with `ggplot2`, and +* `fortify()`, which enables converting a custom object to a tidy `data.frame` + +For example, if you want to implement visualizations for `some_r_class` objects, you need to implement the following: + +* `fortify.some_r_class()` to extract neccessary information into a `data.frame` object +* `autoplot.some_r_class()` that takes what `fortify.some_r_class()` returns and create suitable visualization using `ggplot2` syntax + + +### Contribution guidelines and standards + +Before sending your pull request for +[review](https://github.com/sinhrks/ggfortify/pulls), +make sure your changes are consistent with the guidelines and follow the +coding style described in this document. + +#### General guidelines and philosophy for contribution + +* Include unit tests when you contribute new features, as they help to + a) prove that your code works correctly, and b) guard against future breaking + changes to lower the maintenance cost. +* Bug fixes also generally require unit tests, because the presence of bugs + usually indicates insufficient test coverage. + +#### Unit tests and Continuous integration + +* Run `devtools::test("pathToPackage")` to execute all the unit tests locally. +* Unit tests are triggered automatically on [Travis CI](https://travis-ci.org) so you should be able to locate your test result [here](https://travis-ci.org/sinhrks/ggfortify/pull_requests). + +#### Coding style + +We are following Google's R style guide that can be found [here](https://google.github.io/styleguide/Rguide.xml). diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..6c94901 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,72 @@ +Package: ggfortify +Type: Package +Title: Data Visualization Tools for Statistical Analysis Results +Version: 0.4.11 +Date: 2020-10-02 +Authors@R: c( + person("Masaaki", "Horikoshi", role = c("aut"), + email = "sinhrks@gmail.com"), + person("Yuan", "Tang", role = c("aut", "cre"), + email = "terrytangyuan@gmail.com", + comment = c(ORCID = "0000-0001-5243-233X")), + person("Austin", "Dickey", role = c("ctb")), + person("Matthias", "GreniƩ", role = c("ctb")), + person("Ryan", "Thompson", role = c("ctb")), + person("Luciano", "Selzer", role = c("ctb")), + person("Dario", "Strbenac", role = c("ctb")), + person("Kirill", "Voronin", role = c("ctb")), + person("Damir", "Pulatov", role = c("ctb")) + ) +Maintainer: Yuan Tang +URL: https://github.com/sinhrks/ggfortify +BugReports: https://github.com/sinhrks/ggfortify/issues +Encoding: UTF-8 +Description: Unified plotting tools for statistics commonly used, such as GLM, + time series, PCA families, clustering and survival analysis. The package offers + a single plotting interface for these analysis results and plots in a unified + style using 'ggplot2'. +License: GPL-2 +VignetteBuilder: knitr +Depends: + methods, + ggplot2 (>= 2.0.0) +Imports: + dplyr (>= 0.3), + tidyr, + gridExtra, + grid, + scales, + stringr, + tibble +Suggests: + testthat, + cluster, + changepoint, + dlm, + fGarch, + forecast, + ggrepel, + glmnet, + grDevices, + KFAS, + knitr, + lintr, + mapdata, + markdown, + MASS, + MSwM, + nlme, + raster, + ROCR, + sp, + stats, + strucchange, + survival, + timeSeries, + tseries, + utils, + vars, + xts, + zoo, + lfda +RoxygenNote: 7.1.0 diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..e5c2181 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,24 @@ +Please go to Stack Overflow for help and support with a [minimal reproducible example](https://stackoverflow.com/help/mcve): + +https://stackoverflow.com/questions/tagged/ggfortify + +If you open a GitHub issue, here is our policy: + +1. It must be a bug, a feature request, or a significant problem with documentation (for small docs fixes please send a PR instead). +2. The form below must be filled out. + +**Here's why we have that policy**: ggfortify developers respond to issues. We want to focus on work that benefits the whole community, e.g., fixing bugs and adding features. Support only helps individuals. GitHub also notifies thousands of people when issues are filed. We want them to see you communicating an interesting problem, rather than being redirected to Stack Overflow. + +------------------------ + +### System information +- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: +- **ggfortify installed from (e.g. CRAN or Github)**: +- **ggfortify version**: +- **Exact command to reproduce**: + +### Describe the problem +Describe the problem clearly here. Be sure to convey here why it's a bug in ggfortify or a feature request. + +### Source code / logs / plots +Include any logs, source code, and plots that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..e0f4a6b --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,151 @@ +# Generated by roxygen2: do not edit by hand + +S3method(autoplot,Arima) +S3method(autoplot,HoltWinters) +S3method(autoplot,KFS) +S3method(autoplot,Line) +S3method(autoplot,Lines) +S3method(autoplot,MSM.lm) +S3method(autoplot,Polygon) +S3method(autoplot,Polygons) +S3method(autoplot,RasterBrick) +S3method(autoplot,RasterCommon) +S3method(autoplot,RasterLayer) +S3method(autoplot,RasterStack) +S3method(autoplot,SpatialCommon) +S3method(autoplot,SpatialLines) +S3method(autoplot,SpatialLinesDataFrame) +S3method(autoplot,SpatialPoints) +S3method(autoplot,SpatialPointsDataFrame) +S3method(autoplot,SpatialPolygons) +S3method(autoplot,SpatialPolygonsDataFrame) +S3method(autoplot,aareg) +S3method(autoplot,acf) +S3method(autoplot,ar) +S3method(autoplot,basis) +S3method(autoplot,bats) +S3method(autoplot,breakpoints) +S3method(autoplot,clara) +S3method(autoplot,cpt) +S3method(autoplot,cv.glmnet) +S3method(autoplot,decomposed.ts) +S3method(autoplot,density) +S3method(autoplot,dist) +S3method(autoplot,dlmFiltered) +S3method(autoplot,ets) +S3method(autoplot,fGARCH) +S3method(autoplot,factanal) +S3method(autoplot,fanny) +S3method(autoplot,forecast) +S3method(autoplot,fracdiff) +S3method(autoplot,ggmultiplot) +S3method(autoplot,ggplot) +S3method(autoplot,glm) +S3method(autoplot,glmnet) +S3method(autoplot,irts) +S3method(autoplot,kmeans) +S3method(autoplot,lfda) +S3method(autoplot,list) +S3method(autoplot,lm) +S3method(autoplot,map) +S3method(autoplot,matrix) +S3method(autoplot,nnetar) +S3method(autoplot,partition) +S3method(autoplot,pca_common) +S3method(autoplot,performance) +S3method(autoplot,prcomp) +S3method(autoplot,princomp) +S3method(autoplot,silhouette) +S3method(autoplot,spec) +S3method(autoplot,stepfun) +S3method(autoplot,stl) +S3method(autoplot,survfit) +S3method(autoplot,timeSeries) +S3method(autoplot,ts) +S3method(autoplot,tsmodel) +S3method(autoplot,varprd) +S3method(autoplot,xts) +S3method(autoplot,zooreg) +S3method(fitted,ar) +S3method(fortify,Arima) +S3method(fortify,HoltWinters) +S3method(fortify,KFS) +S3method(fortify,MSM.lm) +S3method(fortify,RasterBrick) +S3method(fortify,RasterCommon) +S3method(fortify,RasterLayer) +S3method(fortify,RasterStack) +S3method(fortify,SpatialCommon) +S3method(fortify,SpatialLines) +S3method(fortify,SpatialPoints) +S3method(fortify,SpatialPointsDataFrame) +S3method(fortify,aareg) +S3method(fortify,acf) +S3method(fortify,ar) +S3method(fortify,basis) +S3method(fortify,bats) +S3method(fortify,breakpoints) +S3method(fortify,breakpointsfull) +S3method(fortify,clara) +S3method(fortify,cpt) +S3method(fortify,cv.glmnet) +S3method(fortify,decomposed.ts) +S3method(fortify,density) +S3method(fortify,dist) +S3method(fortify,dlmFiltered) +S3method(fortify,ets) +S3method(fortify,fGARCH) +S3method(fortify,factanal) +S3method(fortify,fanny) +S3method(fortify,forecast) +S3method(fortify,fracdiff) +S3method(fortify,glmnet) +S3method(fortify,irts) +S3method(fortify,kmeans) +S3method(fortify,lfda) +S3method(fortify,list) +S3method(fortify,matrix) +S3method(fortify,nnetar) +S3method(fortify,pam) +S3method(fortify,partition) +S3method(fortify,performance) +S3method(fortify,prcomp) +S3method(fortify,princomp) +S3method(fortify,silhouette) +S3method(fortify,spec) +S3method(fortify,stepfun) +S3method(fortify,stl) +S3method(fortify,survfit) +S3method(fortify,table) +S3method(fortify,timeSeries) +S3method(fortify,ts) +S3method(fortify,tsmodel) +S3method(fortify,varprd) +S3method(grid.draw,ggmultiplot) +S3method(residuals,ar) +export(fortify_map) +export(ggbiplot) +export(ggcpgram) +export(ggdistribution) +export(ggfreqplot) +export(ggtsdiag) +export(rbind_ts) +export(unscale) +exportClasses(ggmultiplot) +import(dplyr) +import(ggplot2) +import(methods) +importFrom(grid,grid.draw) +importFrom(gridExtra,arrangeGrob) +importFrom(gridExtra,grid.arrange) +importFrom(scales,percent) +importFrom(stats,as.formula) +importFrom(stats,complete.cases) +importFrom(stats,predict) +importFrom(stats,reshape) +importFrom(stats,residuals) +importFrom(stats,weights) +importFrom(stringr,str_wrap) +importFrom(tibble,as_tibble) +importFrom(tidyr,gather_) +importFrom(utils,installed.packages) diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..bac9484 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,94 @@ +## ggfortify development version (master branch) + +TBA + +## ggfortify 0.4.11 + +* Added support of Silhouette plot for `cluster::silhouette` objects, thanks to @damirpolat. +* Fixed issue with `autoplot.lm(which = 2)` when residuals have `AsIs` type, thanks to @richierocks. +* Added `markdown` to `Suggests`. For context, please see [this issue](https://github.com/yihui/knitr/issues/1864). + +## ggfortify 0.4.10 + +* This is a minor release of the package with fixes in tests to be compatible with `survival` (>=3.1-12). + +## ggfortify 0.4.9 + +* This is a minor release of the package with fixes for CRAN check results. + +## ggfortify 0.4.8 + +* This is a minor release of the package with fixes to support new major release of `survival` (>=3.1-7). + +## ggfortify 0.4.7 + +* This is a minor release of the package with a couple of fixes for CRAN check results. + +## ggfortify 0.4.6 + +* Fixed CRAN check results for `R-devel` regarding changes in the default method for generating from a discrete uniform distribution used in `sample()`. + +## ggfortify 0.4.5 + +* Updated tests to work with ggplot2 v2.3.0. + +## ggfortify 0.4.4 + +* Added `label.show.legend` argument to hide/show the legend of text labels. +* `ggmultiplot` arranges a single `ggplot` instance with layout that can now be specified by the user. +* Enhanced unit tests: 1) CRAN MKL build can pass; tests are skipped if the required packages are not installed; several test checks are more robust to upstream package changes. + +## ggfortify 0.4.3 + +* Fixed incorrect y-axis label for plotting `cv.glmnet` objects. +* Removed incorrect y-axis label with `scales::percent` for `ggdistribution`. +* Added support of `autoplot.lm()` for character variables, thanks to @lselzer. +* Fixed tests for `forecast::ets()` to be compatible with newer version of `forecast` package, thanks to @robjhyndman. +* Added support for arbitrary functions in `autoplot.survfit()`, thanks to @jonathon-love. + +## ggfortify 0.4.2 + +* Removed `gglagplot` in favor of `forecast::gglagplot`. +* Added support of `survival::survfitms`, thanks to @yoursdearboy. +* Temporarily dropped support for `xts` and `timeSeries` objects. We will try fix them in the next release. + +## ggfortify 0.4.1 + +* Survival plot now displays legend as it is (without prefix / reordering), thanks to @DarioS. + +## ggfortify 0.4.0 + +* Support `ROCR::performance`, thanks to @austin3dickey +* PCA allows to choose the components to plot, thanks to @lselzer. +* LM autoplot fails when a formula contains polynomial regression. +* GLM autoplot fails when a family function is binomial. + +## ggfortify 0.3.0 + +* Our white paper is on R Journal. Type `citation("ggfortify")` for more info. +* Support `splines::basis`. +* Support several `raster` ojects, such as `RasterBrick`, `RasterCommon`, `RasterLayer`, + and `RasterStack`. +* `ggmultiplot` objects can now be saved correctly via `ggplot2::ggsave()`. + +## ggfortify 0.2.0 + +* Components of `prcomp` and `princomp` are now scaled. Scaling can be disabled by + specifying `scale = 0`. +* `autoplot.t` now supports stacked option. +* Support `maps` and `sp` packages. +* Support `ggrepel`. +* Support `ggbiplot`. +* More compatible with recent version of `forecast`, `dplyr`, `tidyr`, etc. + +## ggfortify 0.1.0 + +* Compatible with ggplot2 v2.0.0. +* Support `glmnet`. +* Support `multiplots` from a list of classes supported by autoplot. +* Support `ggmultiplot` extraction getter / setter. +* Support `ggmultiplot` arithmetics. + +## ggfortify 0.0.4 + +* First release on CRAN. diff --git a/R/base_fortify_list.R b/R/base_fortify_list.R new file mode 100644 index 0000000..c889bff --- /dev/null +++ b/R/base_fortify_list.R @@ -0,0 +1,105 @@ +#' Convert list to data.frame +#' +#' @param model \code{list} instance +#' @inheritParams fortify_base +#' @return data.frame +#' @export +fortify.list <- function(model, data = NULL, ...) { + klass <- infer(model) + if (klass == 'mds-like') { + return(ggplot2::fortify(model$points)) + } else if (klass == 'dlmSmooth') { + s <- dlm::dropFirst(model$s) + if (!is.univariate(s, raise = FALSE)) { + s <- s[, 1] + } + return(ggplot2::fortify(s)) + } else if (klass == 'KFASSignal') { + return(ggplot2::fortify(model$signal)) + } + stop('Unable to infer class from input list') +} + +#' Autoplot list +#' +#' @param object \code{list} instance +#' @param data original dataset, if needed +#' @param ... other arguments passed to methods +#' @inheritParams apply_facets +#' @return ggplot +#' @export +autoplot.list <- function(object, data = NULL, + nrow = NULL, ncol = NULL, scales = 'free_y', + ...) { + if (length(object) ==0) { + stop('list length = 0, contains nothing') + } + + klass <- infer(object) + if (klass == 'mds-like') { + return(ggplot2::autoplot(object$points[, 1:2], geom = 'point', ...)) + } else if (klass == 'dlmSmooth') { + s <- dlm::dropFirst(object$s) + if (!is.univariate(s, raise = FALSE)) { + s <- s[, 1] + } + return(ggplot2::autoplot(s, ...)) + } else if (klass == 'KFASSignal') { + return(ggplot2::autoplot(object$signal, ...)) + } + + # if model is a list of a single class instances, try to plot them with facets + if (all(sapply(object, support_autoplot))) { + + p <- lapply(object, function(x) autoplot(x, data = data, nrow = nrow, + ncol = ncol, scales = scales, ...)) + if (is(p[[1]], 'ggmultiplot')) { + p <- unlist(lapply(p, function(x) x@plots), recursive = FALSE) + } + # set default + if (is.null(ncol)) { ncol <- 0 } + if (is.null(nrow)) { nrow <- 0 } + p <- new('ggmultiplot', plots = p, nrow = nrow, ncol = ncol) + return(p) + } + + stop('Unable to infer class from input list') +} + +#' Infer class name +#' +#' @param data list instance +#' @return character +infer <- function(data) { + if (check_names(data, c('points', 'eig', 'x', 'ac', 'GOF'))) { + # cmdscale + return('mds-like') + } else if (check_names(data, c('points', 'stress'))) { + # isoMDS + return('mds-like') + } else if (check_names(data, c('points', 'stress', 'call'))) { + # sammon + return('mds-like') + } else if (check_names(data, c('s', 'U.S', 'D.S'))) { + # dlm::dlmSmooth + return('dlmSmooth') + } else if (check_names(data, c('signal', 'variance'))) { + # KFAS::signal + return('KFASSignal') + } else { + return('list') + } +} + +#' Check data names are equal with expected +#' +#' @param data \code{list} instance to be checked +#' @param expected expected character vector +#' @return logical +check_names <- function(data, expected) { + n <- names(data) + if (length(n) == length(expected) && all(n == expected)) { + return(TRUE) + } + return (FALSE) +} diff --git a/R/base_fortify_ts.R b/R/base_fortify_ts.R new file mode 100644 index 0000000..e5e135c --- /dev/null +++ b/R/base_fortify_ts.R @@ -0,0 +1,519 @@ +#' Convert time-series-like to data.frame +#' +#' @param model time-series-like instance +#' @inheritParams fortify_base +#' @param columns character vector specifies target column name(s) +#' @param is.date logical frag indicates whether the \code{stats::ts} is date or not +#' If not provided, regard the input as date when the frequency is 4 or 12 +#' @param index.name specify column name for time series index +#' @param data.name specify column name for univariate time series data. Ignored in multivariate time series. +#' @param scale logical flag indicating whether to perform scaling each timeseries +#' @param melt logical flag indicating whether to melt each timeseries as variable +#' @return data.frame +#' @examples +#' fortify(AirPassengers) +#' fortify(timeSeries::as.timeSeries(AirPassengers)) +#' fortify(tseries::irts(cumsum(rexp(10, rate = 0.1)), matrix(rnorm(20), ncol=2))) +#' fortify(stats::stl(UKgas, s.window = 'periodic')) +#' fortify(stats::decompose(UKgas)) +#' @export +fortify.ts <- function(model, data = NULL, columns = NULL, is.date = NULL, + index.name = 'Index', data.name = 'Data', + scale = FALSE, melt = FALSE, ...) { + # no need to define `fortify.xts` because zoo package has `fortify.zoo` + if (is(model, 'timeSeries')) { + d <- as.data.frame(model) + dtindex <- as.POSIXct(rownames(d)) + } else if (is(model, 'irts')) { + d <- as.data.frame(model$value) + dtindex <- model$time + } else if (is(model, 'ts')) { + d <- as.data.frame(as.matrix(model)) + dtindex <- get.dtindex(model, is.date = is.date) + } else if (is(model, 'stl')) { + # stl allows only univariate series + ts.data <- model$time.series + orig <- drop(ts.data %*% rep(1, ncol(ts.data))) + + dtindex <- get.dtindex(ts.data, is.date = is.date) + d <- cbind(data.frame(Data = orig), + data.frame(model$time.series)) + } else if (is(model, 'decomposed.ts')) { + dtindex <- get.dtindex(model$x, is.date = is.date) + dtframe <- ggplot2::fortify(model$x) + + # for tbl_df + dtframe <- data.frame(Data = dtframe[['Data']]) + + # trend and random can be multivariate + rndframe <- model$random + colnames(rndframe) <- NULL + dcframe <- data.frame(seasonal = model$seasonal, + trend = model$trend, + remainder = rndframe) + d <- cbind(dtframe, dcframe) + } else { + stop(paste0('Unsupported class for fortify.ts: ', class(model))) + } + dtframe <- data.frame(Index = dtindex) + colnames(dtframe) <- index.name + if (ncol(d) == 1) { + colnames(d) <- data.name + } + d <- cbind(dtframe, d) + + # filtering columns + if (is.null(columns)) { + data.names <- names(d) + columns <- data.names[data.names != index.name] + } else { + d <- dplyr::select_(d, .dots = c(index.name, columns)) + } + + # scaling + if (scale) { + for (col in columns) { + d[[col]] <- base::scale(d[[col]], center = TRUE, scale = TRUE) + } + } + + # unpivot + if (melt) { + d <- tidyr::gather_(d, 'variable', 'value', columns) + } + post_fortify(d) +} + +#' @export +fortify.timeSeries <- fortify.ts + +#' @export +fortify.irts <- fortify.ts + +#' Autoplot time-series-like +#' +#' @param object time-series-like instance +#' @param columns Character vector specifies target column name(s) +#' @param group Character vector specifies grouping +#' @param is.date Logical frag indicates whether the \code{stats::ts} is date or not +#' If not provided, regard the input as date when the frequency is 4 or 12 +#' @param index.name Specify column name for time series index when passing \code{data.frame} via data. +#' @param p \code{ggplot2::ggplot} instance +#' @param ts.scale Logical flag indicating whether to perform scaling each timeseries +#' @param stacked Logical flag indicating whether to stack multivariate timeseries +#' @inheritParams apply_facets +#' @param ts.geom geometric string for time-series. 'line', 'bar', 'ribbon', or 'point' +#' @param ts.colour line colour for time-series +#' @param ts.size point size for time-series +#' @param ts.linetype line type for time-series +#' @param ts.alpha alpha for time-series +#' @param ts.fill fill colour for time-series +#' @param ts.shape point shape for time-series +#' @param geom same as ts.geom +#' @param colour same as ts.colour +#' @param size same as ts.size +#' @param linetype same as ts.linetype +#' @param alpha same as ts.alpha +#' @param fill same as ts.fill +#' @param shape same as ts.shape +#' @inheritParams post_autoplot +#' @param ... other arguments passed to methods +#' @return ggplot +#' @aliases autoplot.xts autoplot.timeSeries autoplot.irts autoplot.stl autoplot.decomposed.ts +#' @examples +#' \dontrun{ +#' data(Canada, package = 'vars') +#' autoplot(AirPassengers) +#' autoplot(UKgas, ts.geom = 'bar') +#' autoplot(Canada) +#' autoplot(Canada, facets = FALSE) +#' +#' library(zoo) +#' autoplot(xts::as.xts(AirPassengers)) +#' autoplot(timeSeries::as.timeSeries(AirPassengers)) +#' its <- tseries::irts(cumsum(rexp(10, rate = 0.1)), matrix(rnorm(20), ncol=2)) +#' autoplot(its) +#' +#' autoplot(stats::stl(UKgas, s.window = 'periodic')) +#' autoplot(stats::decompose(UKgas)) +#' } +#' @export +autoplot.ts <- function(object, columns = NULL, group = NULL, + is.date = NULL, index.name = 'Index', + p = NULL, ts.scale = FALSE, stacked = FALSE, + facets = TRUE, nrow = NULL, ncol = 1, scales = 'free_y', + ts.geom = 'line', ts.colour = NULL, ts.size = NULL, ts.linetype = NULL, + ts.alpha = NULL, ts.fill = NULL, ts.shape = NULL, + geom = ts.geom, colour = ts.colour, size = ts.size, linetype = ts.linetype, + alpha = ts.alpha, fill = ts.fill, shape = ts.shape, + xlim = c(NA, NA), ylim = c(NA, NA), log = "", + main = NULL, xlab = '', ylab = '', asp = NULL, + ...) { + geomfunc <- get_geom_function(geom, allowed = c('line', 'bar', 'point', 'ribbon')) + + # fortify data + if (is.data.frame(object)) { + plot.data <- object + } else { + plot.data <- ggplot2::fortify(object, scale = ts.scale, + is.date = is.date, index.name = index.name) + } + + if (is.null(columns)) { + if (is(object, 'bats') || is(object, 'ets')) { + # for forecast::bats and forecast::ets + columns <- c('Data', 'Level', 'Slope', 'Season') + # Slope and Season can be optionals + columns <- columns[columns %in% names(plot.data)] + } else { + data.names <- names(plot.data) + columns <- data.names[data.names != index.name] + } + } + + if (is.null(colour) && !is.null(fill)) { + colour <- fill + } else if (!is.null(colour) && is.null(fill)) { + if (geom %in% c('bar', 'ribbon')) { + # do not set for line / point to handle as NULL in geom_factory + fill <- colour + } + } + + if (length(columns) > 1) { + .is.univariate <- FALSE + } else { + .is.univariate <- TRUE + facets <- FALSE + stacked <- FALSE + } + # required for shift op + tslen <- nrow(plot.data) + + if (!facets && stacked && geom != 'bar') { + for (i in seq_len(length(columns) - 1)) { + plot.data[columns[i + 1]] <- plot.data[columns[i + 1]] + plot.data[columns[i]] + } + } + # must be done here, because fortify.zoo is defined in zoo package + ts.column <- plot.data[[index.name]] + if (is(ts.column, 'yearmon') || is(ts.column, 'yearqtr')) { + plot.data[[index.name]] <- zoo::as.Date(plot.data[[index.name]]) + } + + group_key <- 'plot_group' + plot.data <- tidyr::gather_(plot.data, group_key, 'value', columns) + + # create ggplot instance if not passed + if (is.null(p)) { + null.p <- TRUE + mapping <- ggplot2::aes_string(x = index.name) + p <- ggplot2::ggplot(data = plot.data, mapping = mapping) + } else { + null.p <- FALSE + } + + if (!facets && stacked) { + # using dplyr::lag may be easier, but it likely to + # cause a trouble in CMD check + value <- plot.data$value + shifted <- c(rep(0, times = tslen), value[1:(length(value) - tslen)]) + plot.data[['base']] <- shifted + } else { + plot.data[['base']] <- 0 + } + + args <- list(geomfunc, plot.data, colour = colour, size = size, + linetype = linetype, alpha = alpha, fill = fill, + shape = shape, stat = 'identity') + if (geom == 'ribbon') { + args['ymin'] <- 'base' + args['ymax'] <- 'value' + } else { + args['y'] <- 'value' + } + + if (facets) { + args['group'] <- group_key + p <- p + do.call(geom_factory, args) + p <- apply_facets(p, ~ plot_group, nrow = nrow, ncol = ncol, scales = scales) + } else { + if (!.is.univariate) { + # ts.colour cannot be used + if (!is.null(colour)) { + warning('multivariate timeseries with facets=FALSE are colorized by variable, colour is ignored') + } + args['colour'] <- group_key + if (geom %in% c('bar', 'ribbon')) { + args['fill'] <- group_key + } + if (geom == 'ribbon' && !stacked && is.null(alpha)) { + args['alpha'] <- 0.5 + } + if (geom == 'bar' && !stacked) { + args['position'] <- 'dodge' + } + } + p <- p + do.call(geom_factory, args) + } + if (null.p) { + p <- p + ggplot2::scale_y_continuous() + } + p <- post_autoplot(p = p, xlim = xlim, ylim = ylim, log = log, + main = main, xlab = xlab, ylab = ylab, asp = asp) + p +} + +#' @export +autoplot.zooreg <- autoplot.ts + +#' @export +autoplot.xts <- autoplot.ts + +#' @export +autoplot.timeSeries <- autoplot.ts + +#' @export +autoplot.irts <- autoplot.ts + +#' Convert time series models (like AR, ARIMA) to \code{data.frame} +#' +#' @param model Time series model instance +#' @param data original dataset, needed for \code{stats::ar}, \code{stats::Arima} +#' @inheritParams fortify_base +#' @param predict Predicted \code{stats::ts} +#' If not provided, try to retrieve from current environment using variable name. +#' @param is.date Logical frag indicates whether the \code{stats::ts} is date or not. +#' If not provided, regard the input as date when the frequency is 4 or 12. +#' @param ts.connect Logical frag indicates whether connects original time-series and predicted values +#' @return data.frame +#' @aliases fortify.ar fortify.Arima fortify.fracdiff +#' fortify.nnetar fortify.HoltWinters fortify.fGARCH +#' @examples +#' fortify(stats::ar(AirPassengers)) +#' fortify(stats::arima(UKgas)) +#' fortify(stats::arima(UKgas), data = UKgas, is.date = TRUE) +#' fortify(forecast::auto.arima(austres)) +#' fortify(forecast::arfima(AirPassengers)) +#' fortify(forecast::nnetar(UKgas)) +#' fortify(stats::HoltWinters(USAccDeaths)) +#' +#' data(LPP2005REC, package = 'timeSeries') +#' x = timeSeries::as.timeSeries(LPP2005REC) +#' d.Garch = fGarch::garchFit(LPP40 ~ garch(1, 1), data = 100 * x, trace = FALSE) +#' fortify(d.Garch) +fortify.tsmodel <- function(model, data = NULL, + predict = NULL, + is.date = NULL, + ts.connect = TRUE, ...) { + + if (is(model, 'Arima') || is(model, 'ar')) { + if (is.null(data)) { + data <- forecast::getResponse(model) + fit <- stats::fitted(model) + } else { + fit <- data - stats::residuals(model) + } + d <- ggplot2::fortify(data, is.date = is.date) + fit <- ggplot2::fortify(fit, data.name = 'Fitted', is.date = is.date) + resid <- ggplot2::fortify(stats::residuals(model), data.name = 'Residuals', is.date = is.date) + + if (!is.null(predict)) { + pred <- ggplot2::fortify(predict$pred, data.name = 'Predicted') + se <- as.vector(predict$se) + pred$lower <- pred$Predicted - se + pred$upper <- pred$Predicted + se + } + } else if (is(model, 'HoltWinters')) { + # same as fracdiff and nnetar + d <- ggplot2::fortify(model$x, is.date = is.date) + fit <- ggplot2::fortify(stats::fitted(model), data.name = 'Fitted', is.date = is.date) + resid <- ggplot2::fortify(stats::residuals(model), data.name = 'Residuals', is.date = is.date) + + if (!is.null(predict)) { + pred <- ggplot2::fortify(predict) + if (! 'upr' %in% names(pred)) { + pred$upr <- pred$Data + pred$lwr <- pred$Data + } + colnames(pred) <- c('Index', 'Predicted', 'upper', 'lower') + } + } else if (is(model, 'fracdiff') || is(model, 'nnetar')) { + d <- ggplot2::fortify(model$x, is.date = is.date) + fit <- ggplot2::fortify(stats::fitted(model), data.name = 'Fitted', is.date = is.date) + resid <- ggplot2::fortify(stats::residuals(model), data.name = 'Residuals', is.date = is.date) + } else if (is(model, 'fGARCH')) { + index <- attr(model@data, 'names') + index <- as.vector(index) + d <- data.frame(Index = index, Data = model@data) + fit <- data.frame(Index = index, Fitted = model@fitted) + resid <- data.frame(Index = index, Residuals = model@residuals) + + if (!is.null(predict)) { + pred <- data.frame(Predicted = predict$meanForecast) + pred$lower <- pred$Predicted - predict$meanError + pred$upper <- pred$Predicted + predict$meanError + } + } else if (is(model, 'dlmFiltered')) { + d <- ggplot2::fortify(model$y, is.date = is.date) + m <- dlm::dropFirst(model$m) + if (!is.univariate(m, raise = FALSE)) { + m <- m[, 1] + } + fit <- ggplot2::fortify(m, data.name = 'Fitted', is.date = is.date) + resid <- ggplot2::fortify(model$y - m, data.name = 'Residuals', is.date = is.date) + } else if (is(model, 'KFS')) { + d <- ggplot2::fortify(model$model$y, is.date = is.date) + m <- model$alphahat + if (is.null(m)) { + m <- model$m + if (is.null(m)) { + stop('Object does not contain smoothed estimates of states.') + } + m[1] <- model$model$y[1] + } + fit <- ggplot2::fortify(m, data.name = 'Fitted', is.date = is.date) + resid <- ggplot2::fortify(model$model$y - m, + data.name = 'Residuals', is.date = is.date) + } else { + stop(paste0('Unsupported class for fortify.Arima: ', class(model))) + } + d <- dplyr::left_join(d, fit, by = 'Index') + d <- dplyr::left_join(d, resid, by = 'Index') + if (!is.null(predict)) { + d <- rbind_ts(pred, d, ts.connect = ts.connect) + } + post_fortify(d) +} + +#' @export +fortify.ar <- fortify.tsmodel + +#' @export +fortify.Arima <- fortify.tsmodel + +#' @export +fortify.tsmodel <- fortify.tsmodel + +#' @export +fortify.HoltWinters <- fortify.tsmodel + +#' @export +fortify.fracdiff <- fortify.tsmodel + +#' @export +fortify.nnetar <- fortify.tsmodel + +#' @export +fortify.fGARCH <- fortify.tsmodel + +#' @export +fortify.dlmFiltered <- fortify.tsmodel + +#' @export +fortify.KFS <- fortify.tsmodel + +#' Autoplot time series models (like AR, ARIMA) +#' +#' @param object Time series model instance +#' @param data original dataset, needed for \code{stats::ar}, \code{stats::Arima} +#' @param predict Predicted \code{stats::ts} +#' If not provided, try to retrieve from current environment using variable name. +#' @param is.date Logical frag indicates whether the \code{stats::ts} is date or not. +#' If not provided, regard the input as date when the frequency is 4 or 12 +#' @param ts.connect Logical frag indicates whether connects original time-series and predicted values +#' @param fitted.geom geometric string for fitted time-series +#' @param fitted.colour line colour for fitted time-series +#' @param fitted.size point size for fitted time-series +#' @param fitted.linetype line type for fitted time-series +#' @param fitted.alpha alpha for fitted time-series +#' @param fitted.fill fill colour for fitted time-series +#' @param fitted.shape point shape for fitted time-series +#' @param predict.geom geometric string for predicted time-series +#' @param predict.colour line colour for predicted time-series +#' @param predict.size point size for predicted time-series +#' @param predict.linetype line type for predicted time-series +#' @param predict.alpha alpha for predicted time-series +#' @param predict.fill fill colour for predicted time-series +#' @param predict.shape point shape for predicted time-series +#' @inheritParams plot_confint +#' @param ... Keywords passed to \code{autoplot.ts} +#' @return ggplot +#' @aliases autoplot.ar autoplot.fracdiff autoplot.nnetar autoplot.HoltWinters autoplot.fGARCH +#' @examples +#' d.ar <- stats::ar(AirPassengers) +#' autoplot(d.ar) +#' autoplot(d.ar, predict = predict(d.ar, n.ahead = 5)) +#' autoplot(stats::arima(UKgas), data = UKgas) +#' autoplot(forecast::arfima(AirPassengers)) +#' autoplot(forecast::nnetar(UKgas), is.date = FALSE) +#' +#' d.holt <- stats::HoltWinters(USAccDeaths) +#' autoplot(d.holt) +#' autoplot(d.holt, predict = predict(d.holt, n.ahead = 5)) +#' autoplot(d.holt, predict = predict(d.holt, n.ahead = 5, prediction.interval = TRUE)) +#' @export +autoplot.tsmodel <- function(object, data = NULL, + predict = NULL, + is.date = NULL, ts.connect = TRUE, + fitted.geom = 'line', + fitted.colour = '#FF0000', fitted.size = NULL, + fitted.linetype = NULL, fitted.alpha = NULL, + fitted.fill = NULL, fitted.shape = NULL, + predict.geom = 'line', + predict.colour = '#0000FF', predict.size = NULL, + predict.linetype = NULL, predict.alpha = NULL, + predict.fill = NULL, predict.shape = NULL, + conf.int = TRUE, + conf.int.colour = '#0000FF', conf.int.linetype = 'none', + conf.int.fill = '#000000', conf.int.alpha = 0.3, + ...) { + fcol <- ifelse(is(object, 'HoltWinters'), 'xhat', 'Fitted') + plot.data <- ggplot2::fortify(object, predict = predict, + data = data, is.date = is.date) + p <- autoplot.ts(plot.data, columns = 'Data', ...) + + # must be passed by ts.