{"filename":"r-cursorrules-prompt-file-best-practices.mdc","content":"---\ndescription: \"Cursor rules for R development with best practices integration.\"\nglobs: **/*\nalwaysApply: false\n---\nYou are an R programming assistant, make sure to use the best practices when programming in R:\n\n## Project Structure and File Organization\n- Organize projects into clear directories: 'R/' (scripts), 'data/' (raw and processed), 'output/' (results, plots), 'docs/' (reports). For R packages, use 'inst/' for external files; for non-packages, consider 'assets/'.\n- Use an 'Rproj' file for each project to manage working directories and settings.\n- Create reusable functions and keep them in separate script files under the 'R/' folder.\n- Use RMarkdown or Quarto for reproducible reports combining code and results. Prefer Quarto if available and installed.\n- Keep raw data immutable; only work with processed data in 'data/processed/'.\n- Use 'renv' for dependency management and reproducibility. All the dependencies must be installed, synchronized, and locked.\n- Version control all projects with Git and use clear commit messages.\n- Give a snake_case consistent naming for the file names. The file names should not be too long.\n- Avoid using unnecessary dependencies. If a task can be achieved relatively easily using base R, use base R and import other packages only when necessary (e.g., measurably faster, more robust, or fewer lines of code).\n\n## Package Structure\n- If the R project is an R package, make sure to mention the dependencies used inside the package within the 'DESCRIPTION' file. All dependencies must have their version number mentioned (e.g: R6 (>= 2.6.1))\n- If the R project is an R package, make sure a 'LICENSE' file is available. \n- If the R project is an R package, make sure a 'NEWS.md' file is available which should track the package's development changes.\n- If the R project is an R package, make sure that each external file used inside the package is saved within the 'inst' folder. Reading the file should be done using the 'system.file' function. \n- If the R project is an R package, Always use 'devtools::load_all' before testing the new functions. \n- If the R project is an R package, run 'devtools::check()' to ensure the package has no issues. Notes are okay; avoid warnings and errors.\n- If the R project is an R package, document functions using roxygen2. Use 'devtools::document()' to generate the required documentation (.Rd files) and 'NAMESPACE' file.\n\n## Naming Conventions\n- snake_case: variables and functions (e.g., \\`total_sales\\`, \\`clean_data()\\`). \n- UpperCamelCase: for R6, S3, S4, S7 class names (e.g., \\`LinearModel\\`).\n- SCREAMING_SNAKE_CASE: constants and global options (e.g., \\`MAX_ITERATIONS\\`).\n- Avoid ambiguous names (e.g., use \\`customer_id\\` instead of \\`id\\`).\n- Use verbs for function names (e.g., \\`plot_data\\`, \\`calculate_mean\\`).\n- Avoid function or variable names that has already been assigned by R, for example avoid 'sd', it's already a function in R. Another example would be 'data'.\n- When working with R6 classes, always prepend a '.' to private methods and fields. An example of a method would be '.get_data()' which will be used as 'private$.get_data()'. \n    \n## Coding Style\n- Follow the [tidyverse style guide](https://style.tidyverse.org/).\n- Use spaces around operators (\\`a + b\\`, not \\`a+b\\`).\n- Keep line length <= 80 characters for readability.\n- Use consistent indentation (2 spaces preferred).\n- Use '#' for inline comments and section headers. Comment only when necessary (e.g., complex code needing explanation). The code should be self‑explanatory.\n- Write modular, reusable functions instead of long scripts.\n- Prefer vectorized operations over loops for performance.\n- Always handle missing values explicitly (\\`na.rm = TRUE\\`, \\`is.na()\\`).\n- When creating an empty object to be filled later, preallocate type and length when possible (e.g., 'x <- character(length = 100)' instead of 'x <- c()').\n- Always use <- for variables' assignment, except when working with 'R6' classes. The methods inside the 'R6' classes are assigned using '='\n- When referencing a function from a package always use the '::' syntax, for example 'dplyr::select'\n- Always use 'glue::glue' for string interpolation instead of 'paste0' or 'paste'\n    \n## Performance and Optimization\n- Profile code with \\`profvis\\` to identify bottlenecks.\n- Prefer vectorized functions and the apply family ('apply', 'lapply', 'sapply', 'vapply', 'mapply', 'tapply') or 'purrr' over explicit loops. When using loops, preallocate type and memory beforehand.\n- Use data.table for large datasets when performance is critical and data can fit in memory.\n- When reading a CSV, prefer 'data.table::fread' or 'readr::read_csv' depending on the codebase. If the codebase is tidyverse‑oriented, prefer 'readr'; otherwise use 'data.table'.\n\n- Use duckdb when data is out of memory.\n- Avoid copying large objects unnecessarily; use references when possible.\n    \n## Testing and Validation\n- Write unit tests with \\`testthat\\`.\n- Use reproducible random seeds (\\`set.seed()\\`) for consistent results.\n- Test functions with edge cases (empty inputs, missing values, outliers).\n- Use R CMD check or \\`devtools::check()\\` for package development.\n    \n## Reproducibility\n- Use RMarkdown or Quarto for reproducible reports combining code and results. Prefer 'Quarto' if already available and installed.\n- Capture session info with \\`sessionInfo()\\` or \\`sessioninfo::session_info()\\`.\n- Pin package versions with \\`renv\\`.\n- Store scripts, data, and results in version control.\n- Document all analysis steps in README or report files.\n    \n## Collaboration and Documentation\n- Write docstrings using roxygen2 for functions and packages.\n- Maintain a clear README with project goals, setup instructions, and usage.\n- Use descriptive commit messages and branches for feature development.\n- Share results via HTML/PDF reports or dashboards (Shiny, flexdashboard).\n- Comment code for clarity, but prefer self-explanatory variable and function names.\n- Use NEWS.md to follow the project development life cycle. \n    \n## Shiny — App Structure & Modules\n- Use Shiny modules (\\`moduleServer\\`, \\`NS()\\`) for encapsulation, reusability, and testability.\n- Each module should have small responsibilities: UI, server (reactive inputs/outputs), and helper functions for unit testing.\n- Keep UI code declarative and separate from data-processing logic.\n- Use \\`session$userData\\` or per-session \\`reactiveValues\\` for session-scoped state, not global variables.\n- Use \\`www/\\` for static assets (JS/CSS/images), served automatically by Shiny.\n- Avoid using 'UIOutput' and 'renderUI' as they make the reactivity logic more complex. Use them only if it is necessary.\n    \n## Advanced Practices\n- Use S3/S4/S7 or R6 classes for complex objects. Choose depending on the context but have a slight preference for R6.\n- Write custom packages for reusable code across projects.\n- Automate workflows with \\`targets\\` for reproducible pipelines.\n- Containerize environments with Docker for deployment.\n- Use CI/CD (GitHub Actions, GitLab CI) to test and deploy R projects.\n  \n## Dependencies\nHave a preference for the following packages when relying on dependencies:\n- purrr for 'list' objects manipulation and functional programming\n- shiny for web application development\n- 'data.table' or 'dplyr' for in-memory data manipulation\n- 'data.table' or 'dplyr' for efficient data import (CSV/TSV, etc.). \n- 'arrow' when dealing with 'parquet' files\n- 'duckdb' when dealing with out of memory data sets.\n- 'ggplot2' for plotting. \n- 'checkmate' for inputs assertion.\n- 'cli' for displaying users' messages.\n- 'glue' for string interpolation.\n- 'mirai' for parallel computing.\n- 'plotly' for interactive plotting.\n- 'renv' for dependency management.\n- 'jsonlite' for working with 'json'. If the json object is large, use 'yyjsonr'.\n- 'Rcpp' when integrating C++ code in the R project.\n"}