diff --git a/.github/workflows/runcodechunks_vignette.yml b/.github/workflows/runcodechunks_vignette.yml index d8ec16d..5efff12 100644 --- a/.github/workflows/runcodechunks_vignette.yml +++ b/.github/workflows/runcodechunks_vignette.yml @@ -24,7 +24,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 2 @@ -44,7 +44,7 @@ jobs: - name: Cache R packages if: runner.os != 'Windows' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ env.R_LIBS_USER }} key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-${{ matrix.config.mlr3 }}-1-${{ hashFiles('.github/depends.Rds') }} @@ -58,7 +58,7 @@ jobs: - name: Run codechunks in vignette run: | - source("R/doubleml_codechunks.R") + source("Code/doubleml_codechunks.R") shell: Rscript {0} - name: Session info diff --git a/.github/workflows/runreplication.yml b/.github/workflows/runreplication.yml index 63722f9..b1425a5 100644 --- a/.github/workflows/runreplication.yml +++ b/.github/workflows/runreplication.yml @@ -1,5 +1,5 @@ # Workflow based on https://blog--simonpcouch.netlify.app/blog/r-github-actions-commit/ -name: Replication +name: Replication of Simulation Study on: schedule: @@ -24,7 +24,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 2 @@ -44,7 +44,7 @@ jobs: - name: Cache R packages if: runner.os != 'Windows' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ env.R_LIBS_USER }} key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-${{ matrix.config.mlr3 }}-1-${{ hashFiles('.github/depends.Rds') }} @@ -56,50 +56,47 @@ jobs: remotes::install_cran("rcmdcheck") shell: Rscript {0} - - name: Introduction and Cross Fit - run: | - source("R/examples_failure_n_500_p_20.R") - shell: Rscript {0} - - name: Run PLR run: | - source("R/sim_plr.R") + source("Code/sim_plr.R") shell: Rscript {0} - name: Run PLIV run: | - source("R/sim_plivX.R") + source("Code/sim_plivX.R") shell: Rscript {0} - name: Run IRM run: | - source("R/sim_irm.R") + source("Code/sim_irm.R") shell: Rscript {0} - name: Run IIVM run: | - source("R/sim_iivm.R") + source("Code/sim_iivm.R") shell: Rscript {0} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: sim-results path: ./simresults/ - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: sim-results path: ./simresults/ - name: Merge results run: | - source("R/merge_plots.R") + source("Code/merge_plots.R") shell: Rscript {0} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: sim-results - path: ./simresults/ + path: | + ./simresults/ + ./Figures/ - name: Session info run: | diff --git a/.github/workflows/runreplication_key_ingredients.yml b/.github/workflows/runreplication_key_ingredients.yml new file mode 100644 index 0000000..46c186f --- /dev/null +++ b/.github/workflows/runreplication_key_ingredients.yml @@ -0,0 +1,76 @@ +# Workflow based on https://blog--simonpcouch.netlify.app/blog/r-github-actions-commit/ +name: Replication Key Ingredients + +on: + schedule: + - cron: "0 9 1 * *" + workflow_dispatch: + +jobs: + replicate-simulation: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (R ${{ matrix.config.r }}; mlr3 ${{ matrix.config.mlr3 }}; DoubleML ${{ matrix.config.DoubleML }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: macos-11, r: 'release', mlr3: 'release', DoubleML: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} + + env: + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + RSPM: ${{ matrix.config.rspm }} + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + + - uses: r-lib/actions/setup-pandoc@v2 + + - name: Query dependencies + run: | + install.packages('remotes') + install.packages('sessioninfo') + saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) + writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") + shell: Rscript {0} + + - name: Cache R packages + if: runner.os != 'Windows' + uses: actions/cache@v4 + with: + path: ${{ env.R_LIBS_USER }} + key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-${{ matrix.config.mlr3 }}-1-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-${{ matrix.config.mlr3 }}-1- + + - name: Install dependencies + run: | + remotes::install_deps(dependencies = TRUE) + remotes::install_cran("rcmdcheck") + shell: Rscript {0} + + - name: Introduction and Cross Fit + run: | + source("Code/examples_failure_n_500_p_20.R") + shell: Rscript {0} + + - uses: actions/upload-artifact@v4 + with: + name: sim-results + path: | + ./simresults/ + ./Figures/ + + - name: Session info + run: | + options(width = 100) + pkgs <- installed.packages()[, "Package"] + sessioninfo::session_info(pkgs, include_base = TRUE) + shell: Rscript {0} diff --git a/.github/workflows/runreplication_sim_inf.yml b/.github/workflows/runreplication_sim_inf.yml index 3f986fe..7277901 100644 --- a/.github/workflows/runreplication_sim_inf.yml +++ b/.github/workflows/runreplication_sim_inf.yml @@ -24,7 +24,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 2 @@ -44,7 +44,7 @@ jobs: - name: Cache R packages if: runner.os != 'Windows' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ env.R_LIBS_USER }} key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-${{ matrix.config.mlr3 }}-1-${{ hashFiles('.github/depends.Rds') }} @@ -58,12 +58,12 @@ jobs: - name: Run SimInf run: | - source("R/sim_siminf.R") + source("Code/sim_siminf.R") shell: Rscript {0} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: - name: sim-siminf-results + name: sim-siminf-results-final path: ./simresults/ - name: Session info diff --git a/R/doubleml_codechunks.R b/Code/doubleml_codechunks.R similarity index 98% rename from R/doubleml_codechunks.R rename to Code/doubleml_codechunks.R index c669193..3a3998b 100644 --- a/R/doubleml_codechunks.R +++ b/Code/doubleml_codechunks.R @@ -244,11 +244,8 @@ doubleml_plr = DoubleMLPLR$new(doubleml_data, ml_l, ml_m) ## ---- eval = TRUE----------------------------------------------------------------------------------------- par_grids = list( - "ml_l" = ParamSet$new(list( - ParamDbl$new("lambda", lower = 0.05, upper = 0.1))), - "ml_m" = ParamSet$new(list( - ParamDbl$new("lambda", lower = 0.05, upper = 0.1)))) - + "ml_l" = ps(lambda = p_dbl(lower = 0.05, upper = 0.1)), + "ml_m" = ps(lambda = p_dbl(lower = 0.05, upper = 0.1))) ## ---- eval = TRUE----------------------------------------------------------------------------------------- # Provide tune settings diff --git a/R/examples_failure_n_500_p_20.R b/Code/examples_failure_n_500_p_20.R similarity index 90% rename from R/examples_failure_n_500_p_20.R rename to Code/examples_failure_n_500_p_20.R index 10ea0a9..9132f0b 100644 --- a/R/examples_failure_n_500_p_20.R +++ b/Code/examples_failure_n_500_p_20.R @@ -11,7 +11,7 @@ lgr::get_logger("mlr3")$set_threshold("warn") # Create a new directory plus subdirectories dir.create("simresults") dir.create("simresults/examples_fail") - +dir.create("Figures") set.seed(1234) n_rep = 1000 @@ -72,7 +72,7 @@ g_nonorth_resc = ggplot(df_nonorth_resc, aes(x = theta_nonorth)) + g_nonorth_resc -ggsave(filename = paste0("simresults/examples_fail/nonorth_resc_n", n_obs, "_p", n_vars, ".pdf"), +ggsave(filename = paste0("Figures/nonorth_resc_n", n_obs, "_p", n_vars, ".pdf"), plot = g_nonorth_resc) ################ @@ -106,7 +106,7 @@ g_orth_nosplit_resc = ggplot(df_orth_nosplit_resc, aes(x = theta_orth_nosplit)) g_orth_nosplit_resc -ggsave(filename = paste0("simresults/examples_fail/orth_nosplit_resc_n", n_obs, "_p", n_vars, ".pdf"), +ggsave(filename = paste0("Figures/orth_nosplit_resc_n", n_obs, "_p", n_vars, ".pdf"), plot = g_orth_nosplit_resc) ########### @@ -140,7 +140,7 @@ g_dml = ggplot(df_dml, aes(x = theta_dml)) + g_dml -ggsave(filename = paste0("simresults/examples_fail/double_ml_n", n_obs, "_p", n_vars, ".pdf"), +ggsave(filename = paste0("Figures/double_ml_n", n_obs, "_p", n_vars, ".pdf"), plot = g_dml) @@ -155,7 +155,7 @@ g_dml_resc = ggplot(df_dml_resc, aes(x = theta_dml)) + g_dml_resc -ggsave(filename = paste0("simresults/examples_fail/double_ml_resc_n", n_obs, "_p", n_vars, ".pdf"), +ggsave(filename = paste0("Figures/double_ml_resc_n", n_obs, "_p", n_vars, ".pdf"), plot = g_dml_resc) @@ -170,20 +170,20 @@ g_dml_orth_resc = ggplot(df_dml_resc, aes(x = theta_dml)) + g_dml_orth_resc -ggsave(filename = paste0("simresults/examples_fail/double_ml_orth_resc_n", n_obs, "_p", n_vars, ".pdf"), +ggsave(filename = paste0("Figures/double_ml_orth_resc_n", n_obs, "_p", n_vars, ".pdf"), plot = g_dml_resc) # Combined plots g_comb1_resc = plot_grid(g_nonorth_resc, g_dml_orth_resc) -ggsave(filename = paste0("simresults/examples_fail/nonorth_doubleml_n", n_obs, "_p", n_vars, "_resc.pdf"), +ggsave(filename = paste0("Figures/nonorth_doubleml_n", n_obs, "_p", n_vars, "_resc.pdf"), plot = g_comb1_resc, width=8, height=3, dpi=150) g_comb2_resc = plot_grid(g_orth_nosplit_resc, g_dml_resc) -ggsave(filename = paste0("simresults/examples_fail/nosplit_doubleml_n", n_obs, "_p", n_vars, "_resc.pdf"), +ggsave(filename = paste0("Figures/nosplit_doubleml_n", n_obs, "_p", n_vars, "_resc.pdf"), plot = g_comb2_resc, width=8, height=3, dpi=150) @@ -215,7 +215,7 @@ g_dml_split_no_cross = ggplot(df_dml_split_no_cross, aes(x = theta_dml_split_no_ g_dml_split_no_cross -ggsave(filename = paste0("simresults/examples_fail/double_ml_resc_no_cross_n", n_obs, "_p", n_vars, ".pdf"), +ggsave(filename = paste0("Figures/double_ml_resc_no_cross_n", n_obs, "_p", n_vars, ".pdf"), plot = g_dml_split_no_cross) @@ -230,5 +230,5 @@ g_dml g_comb3 = plot_grid(g_dml_split_no_cross, g_dml) -ggsave(filename = paste0("simresults/examples_fail/nocrossfit_doubleml_n", n_obs, "_p", n_vars, ".pdf"), +ggsave(filename = paste0("Figures/nocrossfit_doubleml_n", n_obs, "_p", n_vars, ".pdf"), plot = g_comb3, width=8, height=3, dpi=150) diff --git a/R/merge_plots.R b/Code/merge_plots.R similarity index 98% rename from R/merge_plots.R rename to Code/merge_plots.R index 8d7fffe..5b3c7f1 100644 --- a/R/merge_plots.R +++ b/Code/merge_plots.R @@ -10,7 +10,7 @@ library(data.table) library(DoubleML) # Create new subdirectory -dir.create("simresults/merge") +dir.create("Figures") #load raw results and generate plots # PLR @@ -155,5 +155,5 @@ library(cowplot) g_grid = plot_grid(g_plr, g_pliv, g_irm, g_iivm, nrow = 2) g_grid -ggsave(filename = "simresults/merge/simulations_doubleml_key_models.pdf", +ggsave(filename = "Figures/simulations_doubleml_key_models.pdf", plot = g_grid, width=5, height=5, dpi=150) diff --git a/R/sim_iivm.R b/Code/sim_iivm.R similarity index 90% rename from R/sim_iivm.R rename to Code/sim_iivm.R index 60dfcae..cac47c7 100644 --- a/R/sim_iivm.R +++ b/Code/sim_iivm.R @@ -13,6 +13,12 @@ library(doRNG) dir.create("simresults") dir.create("simresults/iivm") +save_plot = FALSE + +if (save_plot) { + dir.create("Figures") +} + date = Sys.Date() learner_name = "regr.cv_glmnet" learner2_name = "classif.cv_glmnet" @@ -92,11 +98,13 @@ g_iivm = ggplot(df_iivm, aes(x = coef_resc)) + g_iivm -ggsave(filename = paste0("simresults/iivm/densplot_IIVM_", n_obs, "_", dim_x, "_", - "_", dml_procedure, "_", n_folds, - "_", n_rep_folds, "_", learner_name, "_", R, - "_", alpha, ".pdf"), - plot = g_iivm) +if (save_plot) { + ggsave(filename = paste0("Figures/densplot_IIVM_", n_obs, "_", dim_x, "_", + "_", dml_procedure, "_", n_folds, + "_", n_rep_folds, "_", learner_name, "_", R, + "_", alpha, ".pdf"), + plot = g_iivm) +} results_summary = data.table( "learner" = learner_name, diff --git a/R/sim_irm.R b/Code/sim_irm.R similarity index 90% rename from R/sim_irm.R rename to Code/sim_irm.R index 5652a98..990f737 100644 --- a/R/sim_irm.R +++ b/Code/sim_irm.R @@ -13,6 +13,12 @@ library(doRNG) dir.create("simresults") dir.create("simresults/irm") +save_plot = FALSE + +if (save_plot) { + dir.create("Figures") +} + date = Sys.Date() learner_name = "regr.cv_glmnet" learner2_name = "classif.cv_glmnet" @@ -92,12 +98,13 @@ g_est = ggplot(df, aes(x = coef_resc)) + g_est -ggsave(filename = paste0("simresults/irm/densplot_IRM_", n_obs, "_", dim_x, "_", - "_", dml_procedure, "_", n_folds, - "_", n_rep_folds, "_", learner_name, "_", R, - "_", alpha, ".pdf"), - plot = g_est) - +if (save_plot) { + ggsave(filename = paste0("Figures/densplot_IRM_", n_obs, "_", dim_x, "_", + "_", dml_procedure, "_", n_folds, + "_", n_rep_folds, "_", learner_name, "_", R, + "_", alpha, ".pdf"), + plot = g_est) +} results_summary = data.table( "learner" = learner_name, "n_folds" = n_folds, diff --git a/R/sim_plivX.R b/Code/sim_plivX.R similarity index 90% rename from R/sim_plivX.R rename to Code/sim_plivX.R index 1835240..312e6b0 100644 --- a/R/sim_plivX.R +++ b/Code/sim_plivX.R @@ -13,6 +13,12 @@ library(doRNG) dir.create("simresults") dir.create("simresults/pliv") +save_plot = FALSE + +if (save_plot) { + dir.create("Figures") +} + date = Sys.Date() learner_name = "regr.cv_glmnet" learner = lrn("regr.cv_glmnet", s = "lambda.min", nfolds = 5) @@ -88,13 +94,13 @@ g_est = ggplot(df, aes(x = coef_resc)) + g_est - -ggsave(filename = paste0("simresults/pliv/densplot_PLIV_", n_obs, "_", dim_x, "_", - "_", dml_procedure, "_", n_folds, - "_", n_rep_folds, "_", learner_name, "_", R, - "_", alpha, ".pdf"), - plot = g_est) - +if (save_plot) { + ggsave(filename = paste0("Figures/densplot_PLIV_", n_obs, "_", dim_x, "_", + "_", dml_procedure, "_", n_folds, + "_", n_rep_folds, "_", learner_name, "_", R, + "_", alpha, ".pdf"), + plot = g_est) +} results_summary = data.table( "learner" = learner_name, diff --git a/R/sim_plr.R b/Code/sim_plr.R similarity index 91% rename from R/sim_plr.R rename to Code/sim_plr.R index 2d99d61..d058445 100644 --- a/R/sim_plr.R +++ b/Code/sim_plr.R @@ -13,6 +13,12 @@ library(doRNG) dir.create("simresults") dir.create("simresults/plr") +save_plot = FALSE + +if (save_plot) { + dir.create("Figures") +} + date = Sys.Date() learner_name = "regr.ranger" @@ -95,11 +101,14 @@ g_est = ggplot(df, aes(x = coef_resc)) + g_est -ggsave(filename = paste0("simresults/plr/densplot_PLR_", n_obs, "_", dim_x, "_", - "_", dml_procedure, "_", n_folds, - "_", n_rep_folds, "_", learner_name, "_", R, - "_", alpha, ".pdf"), - plot = g_est) +if (save_plot) { + + ggsave(filename = paste0("Figures/densplot_PLR_", n_obs, "_", dim_x, "_", + "_", dml_procedure, "_", n_folds, + "_", n_rep_folds, "_", learner_name, "_", R, + "_", alpha, ".pdf"), + plot = g_est) +} results_summary = data.table( "learner" = learner_name, diff --git a/R/sim_siminf.R b/Code/sim_siminf.R similarity index 100% rename from R/sim_siminf.R rename to Code/sim_siminf.R diff --git a/README.Rmd b/README.Rmd index c116d97..d8bf84a 100644 --- a/README.Rmd +++ b/README.Rmd @@ -1,11 +1,11 @@ --- -title: "Replication of Simulations in Bach et al. (2020) - DoubleML - An Object-Oriented Implementation of Double Machine Learning in R" +title: "Replication of Simulations in Bach et al. (forthcoming) - DoubleML - An Object-Oriented Implementation of Double Machine Learning in R" author: "Philipp Bach" date: "`r format(Sys.Date(), format='%b %d, %Y')`" output: github_document --- -In this repository, we list and automatically run the simulation examples presented in [Bach et al. (2020)](https://arxiv.org/abs/2103.09603) +In this repository, we list and automatically run the simulation examples presented in [Bach et al. (forthcoming)](https://arxiv.org/abs/2103.09603) ## Files for Replication of Figures and Results in DoubleML Package Vignette @@ -23,6 +23,7 @@ The examples and results from the paper *DoubleML - An Object-Oriented Implement + Simultaneous inference: `sim_siminf.R` 3. Code chunks: The reproducible code contained in the code chunks is available via + `doubleml_codechunks.R` + + *Note*: The code in `doubleml_codechunks.R` has been automatically produced from the manuscript (`.Rmd`) using `knitr::purl()`, see also Chapter 3.4 of *Xi et al. (2020)* All data sets and DGPs used in the paper can be replicated via corresponding functions as provided in the `DoubleML` package. The required function calls are contained in the code chunks of the paper. The API documentation is available via https://docs.doubleml.org/r/stable/reference/index.html. @@ -34,12 +35,12 @@ In case you have any questions, do not hesitate to contact philipp.bach@uni-hamb If you use the DoubleML package a citation is highly appreciated: -Bach, P., Chernozhukov, V., Kurz, M. S., and Spindler, M. (2021), DoubleML - An Object-Oriented Implementation of Double Machine Learning in Python, arXiv:2104.03220. +Bach, P., Chernozhukov, V., Kurz, M. S., Spindler, M., and Klaassen, S. (2021), DoubleML - An Object-Oriented Implementation of Double Machine Learning in R, arXiv:2103.09603. ``` @misc{DoubleML2021R, title={{DoubleML} -- {A}n Object-Oriented Implementation of Double Machine Learning in {R}}, - author={P. Bach and V. Chernozhukov and M. S. Kurz and M. Spindler}, + author={P. Bach and V. Chernozhukov and M. S. Kurz and M. Spindler and S. Klaassen}, year={2021}, eprint={2103.09603}, archivePrefix={arXiv}, @@ -61,4 +62,7 @@ We would like to thank Simon Couch for providing [a detailed blogpost on how to ## References -Bach, P., Chernozhukov, V., Kurz, M. S., and Spindler, M. (2021), DoubleML - An Object-Oriented Implementation of Double Machine Learning in Python, arXiv:2104.03220. +Bach, P., Chernozhukov, V., Kurz, M. S., Spindler, M. and Klaassen, S. (2021), DoubleML - An Object-Oriented Implementation of Double Machine Learning in R, arXiv:2104.03220. + +Xie, Y., Dervieux, C., & Riederer, E. (2020). R markdown cookbook. CRC Press. + diff --git a/README.md b/README.md index 006f748..6f167d4 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -Replication of Simulations in Bach et al. (2020) - DoubleML - An +Replication of Simulations in Bach et al. (forthcoming) - DoubleML - An Object-Oriented Implementation of Double Machine Learning in R ================ Philipp Bach -Aug 02, 2021 +Mrz 27, 2023 In this repository, we list and automatically run the simulation examples presented in [Bach et -al. (2020)](https://arxiv.org/abs/2103.09603) +al. (forthcoming)](https://arxiv.org/abs/2103.09603) ## Files for Replication of Figures and Results in DoubleML Package Vignette @@ -16,19 +16,22 @@ the R files listed in the following: 1. Section 4: *Basic idea and key ingredients of double machine learning* - Code for replication of simulation examples - - `examples_failure_n_500_p_20.R` + - `examples_failure_n_500_p_20.R` 2. Section 7.8: *A short simulation study* - Code for replication of simulation results - - Cross-fitting: `examples_failure_n_500_p_20.R` - - PLR: `sim_plr.R` - - PLIV: `sim_plivX.R` - - IRM: `sim_irm.R` - - IIVM: `sim_IIVM.R` - - Merging plots: `merge_plots.R` - - Simultaneous inference: `sim_siminf.R` + - Cross-fitting: `examples_failure_n_500_p_20.R` + - PLR: `sim_plr.R` + - PLIV: `sim_plivX.R` + - IRM: `sim_irm.R` + - IIVM: `sim_IIVM.R` + - Merging plots: `merge_plots.R` + - Simultaneous inference: `sim_siminf.R` 3. Code chunks: The reproducible code contained in the code chunks is available via - - `doubleml_codechunks.R` + - `doubleml_codechunks.R` + - *Note*: The code in `doubleml_codechunks.R` has been automatically + produced from the manuscript (`.Rmd`) using `knitr::purl()`, see + also Chapter 3.4 of *Xi et al. (2020)* All data sets and DGPs used in the paper can be replicated via corresponding functions as provided in the `DoubleML` package. The @@ -48,13 +51,13 @@ In case you have any questions, do not hesitate to contact If you use the DoubleML package a citation is highly appreciated: -Bach, P., Chernozhukov, V., Kurz, M. S., and Spindler, M. (2021), -DoubleML - An Object-Oriented Implementation of Double Machine Learning -in Python, arXiv:2104.03220. +Bach, P., Chernozhukov, V., Kurz, M. S., Spindler, M., and Klaassen, S. +(2021), DoubleML - An Object-Oriented Implementation of Double Machine +Learning in R, arXiv:2103.09603. @misc{DoubleML2021R, title={{DoubleML} -- {A}n Object-Oriented Implementation of Double Machine Learning in {R}}, - author={P. Bach and V. Chernozhukov and M. S. Kurz and M. Spindler}, + author={P. Bach and V. Chernozhukov and M. S. Kurz and M. Spindler and S. Klaassen}, year={2021}, eprint={2103.09603}, archivePrefix={arXiv}, @@ -77,6 +80,9 @@ replication of the simulation results. ## References -Bach, P., Chernozhukov, V., Kurz, M. S., and Spindler, M. (2021), -DoubleML - An Object-Oriented Implementation of Double Machine Learning -in Python, arXiv:2104.03220. +Bach, P., Chernozhukov, V., Kurz, M. S., Spindler, M. and Klaassen, S. +(2021), DoubleML - An Object-Oriented Implementation of Double Machine +Learning in R, arXiv:2104.03220. + +Xie, Y., Dervieux, C., & Riederer, E. (2020). R markdown cookbook. CRC +Press.