{"id":32201002,"url":"https://github.com/marcellgranat/currr","last_synced_at":"2026-02-27T09:16:29.925Z","repository":{"id":65858824,"uuid":"597103882","full_name":"MarcellGranat/currr","owner":"MarcellGranat","description":"The currr package is a wrapper for the purrr::map() family but extends the iteration process with a certain number of checkpoints ( currr = checkpoints + purr), where the evaluated results are saved, and we can always restart from there.","archived":false,"fork":false,"pushed_at":"2024-08-21T13:46:26.000Z","size":64,"stargazers_count":20,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-22T03:58:32.220Z","etag":null,"topics":["checkpoints","parallel-computing","purrr"],"latest_commit_sha":null,"homepage":"https://marcellgranat.com/currr","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MarcellGranat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-02-03T16:30:26.000Z","updated_at":"2025-03-22T10:27:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"d0b18ab9-367b-4628-9580-6dcce422b74c","html_url":"https://github.com/MarcellGranat/currr","commit_stats":{"total_commits":18,"total_committers":1,"mean_commits":18.0,"dds":0.0,"last_synced_commit":"12dcb8f8e7c57e6b04a10ffa9d188c5e22a371cb"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/MarcellGranat/currr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcellGranat%2Fcurrr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcellGranat%2Fcurrr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcellGranat%2Fcurrr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcellGranat%2Fcurrr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MarcellGranat","download_url":"https://codeload.github.com/MarcellGranat/currr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcellGranat%2Fcurrr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280376547,"owners_count":26320275,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-22T02:00:06.515Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["checkpoints","parallel-computing","purrr"],"created_at":"2025-10-22T03:58:46.360Z","updated_at":"2025-10-22T03:58:47.449Z","avatar_url":"https://github.com/MarcellGranat.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# currr \u003cimg src=\"https://raw.githubusercontent.com/MarcellGranat/marcellgranat-website/main/static/currr/logo.png\" align=\"right\" width=\"120px\" /\u003e\n\n\u003c!-- badges: start --\u003e\n\n[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/currr)](https://cran.r-project.org/package=currr)\n\u003c!-- badges: end --\u003e\n\n## Overview\n\n\u003e A long journey is best broken into small steps, and the importance of\n\u003e taking a rest must never be underestimated.\n\nThe **currr** package is a wrapper for the `purrr::map()` family but\nextends the iteration process with a certain number of **checkpoints**\n(`currr` = `c`heckpoints + `purrr`), where the evaluated results are\nsaved, and we can always restart from there.\n\n\u003cimg src=\"https://raw.githubusercontent.com/MarcellGranat/marcellgranat-website/main/static/currr/example.gif\" align=\"center\" /\u003e\n\nImplementations of the family of map() functions with a frequent saving\nof the intermediate results. The contained functions let you **start**\nthe evaluation of the iterations **where you stopped** (reading the\nalready evaluated ones from the cache), and **work with the currently\nevaluated iterations** while the remaining ones are running in a\nbackground job. **Parallel** computing is also easier with the `workers`\nparameter.\n\n## Installation\n\n``` r\ninstall.packages(\"currr\")\n```\n\n## Usage\n\nThe following example uses `currr` to present an everyday issue: run a\ntime-demanding iteration, but you want to rerun it again.\n\n``` r\nlibrary(tidyverse)\nlibrary(currr)\n\noptions(currr.folder = \".currr\", currr.wait = Inf)\n# folder in your wd, where to save cache data\n\navg_n \u003c- function(.data, .col, x) {\n  # meaningless function that takes about 1 sec\n  Sys.sleep(1)\n  \n  .data |\u003e\n    dplyr::pull({{ .col }}) |\u003e\n    (\\(m) mean(m) * x) ()\n}\n```\n\n### Checkpoints\n\n``` r\ntictoc::tic(msg = \"First evaluation\")\n\ncp_map(.x = 1:50, .f = avg_n, .data = iris, \n       .col = Sepal.Length, \n       name = \"iris_mean\") |\u003e \n  head(3)\n#\u003e [[1]]\n#\u003e [1] 5.843333\n#\u003e \n#\u003e [[2]]\n#\u003e [1] 11.68667\n#\u003e \n#\u003e [[3]]\n#\u003e [1] 17.53\n\ntictoc::toc() # ~ 1:50 =\u003e 50 x 1 sec\n#\u003e First evaluation: 50.351 sec elapsed\n\n\n\ntictoc::tic(msg = \"Second evaluation\")\n\ncp_map(.x = 1:50, .f = avg_n, .data = iris, \n       .col = Sepal.Length, \n       name = \"iris_mean\") |\u003e \n  head(3)\n#\u003e ✓ Everything is unchanged. Reading cache.\n#\u003e [[1]]\n#\u003e [1] 5.843333\n#\u003e \n#\u003e [[2]]\n#\u003e [1] 11.68667\n#\u003e \n#\u003e [[3]]\n#\u003e [1] 17.53\n\ntictoc::toc() # ~ 0 sec\n#\u003e Second evaluation: 0.034 sec elapsed\n```\n\nIf the `.x` input and `.f` are the same, then the 2nd time you call the\nfunction, it reads the outcome from the specified folder (`.currr`).\nAlso if `.x` changes, but some of its part remain the same, then that\npart is taken from the previously saved results, and only the new\nelements of `.x` are called for evaluation. (If `.f` changes, then the\nprocess will start from zero.)\n\n``` r\ntictoc::tic(msg = \"Partly modification\")\n\ncp_map(.x = 20:60, .f = avg_n, .data = iris, \n       .col = Sepal.Length, \n       name = \"iris_mean\") |\u003e \n  head(3)\n#\u003e ⚠ .x has changed. Looking for mathcing result to save them as cache\n#\u003e ◌ Cache updated based on the new .x values\n#\u003e [[1]]\n#\u003e [1] 116.8667\n#\u003e \n#\u003e [[2]]\n#\u003e [1] 122.71\n#\u003e \n#\u003e [[3]]\n#\u003e [1] 128.5533\n\ntictoc::toc() # ~ 50:60 =\u003e 10 x 1 sec\n#\u003e Partly modification: 10.378 sec elapsed\n```\n\nYou can remove the cache files, if you want to reset the process (or\nremove the already unnecessary files from your folder).\n\n``` r\n# only cache files for iris_mean\nremove_currr_cache(\"iris_mean\")\n\n# all cache files\nremove_currr_cache()\n```\n\n### Parallel process\n\nYou can also use multicore process (built on the `parallel` package).\nAfter evaluation, the computation will automatically reset to\nsequential.\n\n``` r\noptions(currr.workers = 5) # \u003c\n\ntictoc::tic(msg = \"Parallel computation\")\n\ncp_map(.x = 1:50, .f = avg_n, .data = iris, \n       .col = Sepal.Length, \n       name = \"iris_mean\") |\u003e \n  head(3)\n#\u003e [[1]]\n#\u003e [1] 5.843333\n#\u003e \n#\u003e [[2]]\n#\u003e [1] 11.68667\n#\u003e \n#\u003e [[3]]\n#\u003e [1] 17.53\n\ntictoc::toc() # ~ 50 / 5 =\u003e 10 sec\n#\u003e Parallel computation: 21.159 sec elapsed\n```\n\n### Background process\n\nThis is another functionality that makes `currr` to be cool. Working in\nRStudio you can set the `wait` parameter to 0-1/1+, define how many\niterations you want to wait, and then let R work on the remaining\niterations in the background, while you can work with the evaluated\nones. If wait \\\u003c 1, then it is interpreted as what proportion of the\niterations you want to wait. Whenever you recall the function, it will\nreturn the already evaluated ones (use the `fill` parameter to specify\nwhether you want to get `NULL`s to the pending ones.)\n\n``` r\noptions(currr.wait = 20, currr.fill = FALSE)\n```\n\n\u003cimg src=\"https://raw.githubusercontent.com/MarcellGranat/marcellgranat-website/main/static/currr/example2.gif\" align=\"center\" /\u003e\n\nIn the example above, you get your results, when 20 iterations are\nevaluated, but the job in the background keeps running.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcellgranat%2Fcurrr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcellgranat%2Fcurrr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcellgranat%2Fcurrr/lists"}