{"id":32207084,"url":"https://github.com/tony-aw/broadcast","last_synced_at":"2026-02-22T10:41:22.427Z","repository":{"id":287244701,"uuid":"910437795","full_name":"tony-aw/broadcast","owner":"tony-aw","description":"R Package Broadcast: Broadcasted Array Operations Like ‘NumPy’","archived":false,"fork":false,"pushed_at":"2026-02-18T19:28:28.000Z","size":301285,"stargazers_count":27,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-02-18T23:41:05.348Z","etag":null,"topics":["cran","cran-r","data-manipulation","fastverse","high-performance","multidimensional-arrays","numpy","r","r-package","rstats","rstats-package","scientific-computing"],"latest_commit_sha":null,"homepage":"https://tony-aw.github.io/broadcast/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tony-aw.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-31T09:17:18.000Z","updated_at":"2026-02-18T19:28:31.000Z","dependencies_parsed_at":"2025-10-26T22:23:02.959Z","dependency_job_id":"33910f1b-b50b-472c-b502-4f0af769d699","html_url":"https://github.com/tony-aw/broadcast","commit_stats":null,"previous_names":["tony-aw/broadcast"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/tony-aw/broadcast","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tony-aw%2Fbroadcast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tony-aw%2Fbroadcast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tony-aw%2Fbroadcast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tony-aw%2Fbroadcast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tony-aw","download_url":"https://codeload.github.com/tony-aw/broadcast/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tony-aw%2Fbroadcast/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29658170,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T16:33:43.953Z","status":"ssl_error","status_checked_at":"2026-02-20T16:33:43.598Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cran","cran-r","data-manipulation","fastverse","high-performance","multidimensional-arrays","numpy","r","r-package","rstats","rstats-package","scientific-computing"],"created_at":"2025-10-22T05:45:43.658Z","updated_at":"2026-02-22T10:41:22.421Z","avatar_url":"https://github.com/tony-aw.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"man/figures/broadcast.png\" height=\"300\"/\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n‘R’-package ‘broadcast’: Broadcasted Array Operations Like ‘NumPy’\n\u003c/p\u003e\n\u003c!-- badges: start --\u003e\n\n[![R build\nstatus](https://github.com/tony-aw/broadcast/workflows/R-CMD-check/badge.svg)](https://github.com/tony-aw/broadcast/actions)\n[![Project Status: Active - The project has reached a stable, usable\nstate and is being actively\ndeveloped.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)\n[![](https://img.shields.io/badge/ORCID-0000--0001--9498--8379-green.svg)](https://orcid.org/0000-0001-9498-8379)\n[![](https://www.r-pkg.org/badges/version/broadcast)](https://cran.r-project.org/package=broadcast)\n[![Dependencies](https://tinyverse.netlify.app/badge/broadcast)](https://cran.r-project.org/package=broadcast)  \n\u003c!-- badges: end --\u003e\n\n \n\n## 🗺️Overview\n\n‘broadcast’ is an efficient ‘C’/‘C++’ - based ‘R’ package that, as the\nname suggests, performs “array broadcasting” (similar to broadcasting in\nthe ‘Numpy’ module for ‘Python’).\n\nIn the context of operations involving 2 (or more) arrays,\n“broadcasting” refers to efficiently recycling array dimensions, without\nmaking copies.  \nThis is considerably **faster** and **more memory-efficient** than R’s\nregular dimensions replication mechanism.\n\nKey Features (click on the 🔍 to show or hide):\n\n\u003cdetails\u003e\n\u003csummary\u003e\n\u003cb\u003e\u003ca style=\"cursor: pointer;\"\u003eBroadcasted Infix Operators 🔍 \u003c/a\u003e\u003c/b\u003e\n\u003c/summary\u003e\n\nConsider computing the addition of these arrays `x` and `y`:\n\n``` r\n(x \u003c- array(1:15, c(3, 5)))\n#\u003e      [,1] [,2] [,3] [,4] [,5]\n#\u003e [1,]    1    4    7   10   13\n#\u003e [2,]    2    5    8   11   14\n#\u003e [3,]    3    6    9   12   15\n(y \u003c- array(1:5 * 100, c(1, 5)))\n#\u003e      [,1] [,2] [,3] [,4] [,5]\n#\u003e [1,]  100  200  300  400  500\n```\n\nThis cannot be done efficiently in base ‘R’; it **can** be done fast and\nmemory-efficiently with the ‘broadcast’ package:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd height=\"1\"\u003e\nBase ‘R’\n\u003c/th\u003e\n\u003ctd height=\"1\"\u003e\n‘broadcast’ package\n\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n``` r\nx + y\nError in x + y : non-conformable arrays\n\n# You *could* do the following....\nx + y[rep(1L, 3L),]\n# ... but if x or y is very large: \nError: cannot allocate vector of size\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n``` r\nbroadcaster(x) \u003c- TRUE\nbroadcaster(y) \u003c- TRUE\nx + y\n#\u003e      [,1] [,2] [,3] [,4] [,5]\n#\u003e [1,]  101  204  307  410  513\n#\u003e [2,]  102  205  308  411  514\n#\u003e [3,]  103  206  309  412  515\n#\u003e broadcaster\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n‘broadcast’ supports a wide range of infix operators, including\narithmetic-, relational-, Boolean- string- and bit-wise operators.\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\n\u003cb\u003e\u003ca style=\"cursor: pointer;\"\u003eBroadcasted Array Binding 🔍 \u003c/a\u003e\u003c/b\u003e\n\u003c/summary\u003e\n\nUsing broadcasting, `bind_array()` from the ‘broadcast’ package can bind\narrays together in ways that cannot efficiently be done with `rbind()`,\n`cbind()`, or `abind::abind()`. Consider, for example, column-binding\nthese arrays `x` and `y`:\n\n``` r\n(x \u003c- array(1:12, c(3, 4)))\n#\u003e      [,1] [,2] [,3] [,4]\n#\u003e [1,]    1    4    7   10\n#\u003e [2,]    2    5    8   11\n#\u003e [3,]    3    6    9   12\n(y \u003c- array(1:4 * 100, c(1, 4)))\n#\u003e      [,1] [,2] [,3] [,4]\n#\u003e [1,]  100  200  300  400\n```\n\nThis cannot be done efficiently in base ‘R’; it **can** be done fast and\nmemory-efficiently with the ‘broadcast’ package:\n\n\u003ctable cellspacing=\"0\" cellpadding=\"0\"\u003e\n\u003ctr\u003e\n\u003ctd\u003e\nBase ‘R’\n\u003c/th\u003e\n\u003ctd\u003e\n‘broadcast’ package\n\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n``` r\ncbind(x, y)\nError in cbind(x, y) :\n  number of rows of matrices must match\n\n# You *could* do the following....\ncbind(x, y[rep(1L, 3L),])\n# ... but if x or y is very large:\nError: cannot allocate vector of size\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n``` r\nbind_array(list(x, y), along = 2L)\n#\u003e      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]\n#\u003e [1,]    1    4    7   10  100  200  300  400\n#\u003e [2,]    2    5    8   11  100  200  300  400\n#\u003e [3,]    3    6    9   12  100  200  300  400\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n`bind_array()` is also considerably faster and more memory efficient\nthan `abind()`. See the\n[benchmarks](https://tony-aw.github.io/broadcast/about/f_benchmarks_other.html).\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\n\u003cb\u003e\u003ca style=\"cursor: pointer;\"\u003eBroadcasted General Functions 🔍 \u003c/a\u003e\u003c/b\u003e\n\u003c/summary\u003e\n\nThe idea of broadcasted infix operations and broadcasted array binding\nhas been generalized to also include `bcapply()` (a broadcasted\napply-like function), `bc_ifelse()` (broadcasted version of `ifelse()`),\n`bc_strrep()` (broadcasted version of `strrep()`).\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\n\u003cb\u003e\u003ca style=\"cursor: pointer;\"\u003eCasting Methods 🔍 \u003c/a\u003e\u003c/b\u003e\n\u003c/summary\u003e\n\nBroadcast provides casting functions, that cast subset-groups of an\narray to a new dimension, cast nested lists to dimensional lists, and\nvice-versa.  \nThese functions are useful for facilitating complex broadcasted\noperations, though they also have much merit beside broadcasting.\n\nFor example, you cannot broadcast through hierarchies of a list, but you\n**can** broadcast along dimensions. So suppose you have the following\nlist:\n\n``` r\nx \u003c- list(\n  student1 = list(\n    homework1 = sample(0:100, 5),\n    homework2 = sample(0:100, 5),\n    homework3 = sample(0:100, 5)\n  ),\n  student2 = list(\n    homework1 = sample(0:100, 5),\n    homework2 = sample(0:100, 5),\n    homework3 = sample(0:100, 5)\n  ),\n  student3 = list(\n    homework1 = sample(0:100, 5),\n    homework2 = sample(0:100, 5),\n    homework3 = sample(0:100, 5)\n  )\n)\n```\n\nSince all values in the list are numbers, you might want to turn this\ninto a numeric array, to make mathematical computations and analyses on\nit easier.\n\nThis can be done with the ‘broadcast’ package with the following steps.\nFirst, turn the nested list into a shallow (i.e. non-nested),\ndimensional list using `cast_hier2dim()`:\n\n``` r\nx2 \u003c- cast_hier2dim(x, in2out = FALSE, direction.names = 1L)\nprint(x2)\n#\u003e          homework1 homework2 homework3\n#\u003e student1 integer,5 integer,5 integer,5\n#\u003e student2 integer,5 integer,5 integer,5\n#\u003e student3 integer,5 integer,5 integer,5\n```\n\nSecond, turn the shallow (i.e. non-nested), dimensional list into an\natomic array using `cast_shallow2atomic()`:\n\n``` r\nx3 \u003c- cast_shallow2atomic(x2, 1L)\nprint(x3)\n#\u003e , , homework1\n#\u003e \n#\u003e      student1 student2 student3\n#\u003e [1,]       67        6       73\n#\u003e [2,]       38       72       41\n#\u003e [3,]        0       78       37\n#\u003e [4,]       33       84       19\n#\u003e [5,]       86       36       27\n#\u003e \n#\u003e , , homework2\n#\u003e \n#\u003e      student1 student2 student3\n#\u003e [1,]       42       88       19\n#\u003e [2,]       13       36       43\n#\u003e [3,]       81       33       86\n#\u003e [4,]       58      100       69\n#\u003e [5,]       50       43       39\n#\u003e \n#\u003e , , homework3\n#\u003e \n#\u003e      student1 student2 student3\n#\u003e [1,]       96       78       43\n#\u003e [2,]       84       32       24\n#\u003e [3,]       20       83       69\n#\u003e [4,]       53       34       38\n#\u003e [5,]       73       69       50\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\n\u003cb\u003e\u003ca style=\"cursor: pointer;\"\u003eA few Linear Algebra Functions for\nStatistics 🔍 \u003c/a\u003e\u003c/b\u003e\n\u003c/summary\u003e\n\n‘broadcast’ comes with a few linear algebra functions for statistics.\nFor example, the `sd_lc()` function to compute the standard deviation of\na linear combination of variables - regardless of what the distribution\nof the variables is.\n\n\u003c/details\u003e\n\n \n\nThe **Quick-Start Guide** can be found\n[here](https://tony-aw.github.io/broadcast/vignettes/b_quickstart.html).\n\n \n\n## 🤷🏽Why use ‘broadcast’\n\n**Efficiency**\n\nBroadcasting as implemented in the ‘broadcasting’ package is about as\nfast as - and sometimes even faster than - NumPy.  \nThe implementations in the ‘broadcast’ package are also much faster and\nmuch more memory efficient than using base ‘R’ solutions like\n`sweep()`.  \nEfficient programs use less energy and resources, and is thus better for\nthe environment.  \nBenchmarks can be found in the “About” section on the website.\n\n \n\n**Convenience**\n\nHave you ever been bothered by any of the following while programming in\n‘R’:\n\n- Receiving the “non-conformable arrays” error message in a simple array\n  operation, when it intuitively should work?\n- Receiving the “cannot allocate vector of size…” error message because\n  ‘R’ unnecessarily allocated too much memory in array operations?\n- `abind::abind()` being too slow, or ruining the structure of recursive\n  arrays?\n- The `sweep()` and `outer()` functions being too slow or too limiting?\n- that there is no array analogy to `data.table::dcast()`?\n- difficulties in handling deeply nested lists?\n- that certain ‘Numpy’ operations have no equivalent operation in ‘R’?\n\nIf you answered “YES” to any of the above, ‘broadcast’ may be the ‘R’ -\npackage for you.\n\n \n\n**Minimal Dependencies**\n\nBesides linking to ‘Rcpp’, ‘broadcast’ does not depend on, vendor, link\nto, include, or otherwise use any external libraries; ‘broadcast’ was\nessentially made from scratch and can be installed out-of-the-box.\n\nNot using external libraries brings a number of advantages:\n\n- Avoid dependency hell.\n- Avoid wasting time, memory and computing resources for translating\n  between language structures.\n- Ensure consistent behaviour with the rest of ‘R’.\n- Access to CRAN’s quality control (no comparable quality control\n  organization exists for most other programming languages).\n\nSee the [Other\nPackages](https://tony-aw.github.io/broadcast/about/d_other_pkgs.html)\npage for more details on the above points regarding the advantages of\nminimizing dependencies.\n\n \n\n**Tested**\n\nThe ‘broadcast’ package is frequently checked using a large suite of\nunit tests via the [tinytest](https://github.com/markvanderloo/tinytest)\npackage. These tests have a\n[coverage](https://tony-aw.github.io/broadcast/about/g_unit_test_covr.html)\nof over 95%. So the chance of a function from this package breaking\ncompletely is relatively low.\n\n‘broadcast’ is still relatively new package, however, so (small) bugs\nare still very much possible. I encourage users who find bugs to report\nthem promptly to the\n[issues](https://github.com/tony-aw/broadcast/issues) tab on the GitHub\npage, and I will fix them as soon as time permits.\n\n \n\n## 🔧Installation\n\n``` r\n\ninstall.packages(\"broadcast\", type = \"source\")\n```\n\n \n\n \n\n## 📊Status\n\n‘broadcast’ is now available on CRAN! 🎉\n\nIf you have any suggestions or feedback on the package, its\ndocumentation, or even the benchmarks, I encourage you to let me know\n(either as an [Issue](https://github.com/tony-aw/broadcast/issues) or a\n[Discussion](https://github.com/tony-aw/broadcast/discussions)).  \nI’m eager to read your input!\n\n \n\n## 📖Documentation\n\nThe documentation in the ‘broadcast’ website is divided into 3 main\nparts:\n\n- [Guides and\n  Vignettes](https://tony-aw.github.io/broadcast/vignettes/a_readme.html):\n  contains the topic-oriented guides in the form of a few Vignettes.\n- [Reference\n  Manual](https://tony-aw.github.io/broadcast/man/aaa00_broadcast_help.html):\n  contains the function-oriented reference manual.\n- [About](https://tony-aw.github.io/broadcast/about/a_acknowledgements.html):\n  Contains the Acknowledgements, Change logs and License file. Here\n  you’ll also find some information regarding the relationship between\n  ‘broadcast’ and other packages/modules. Benchmarks can also be found\n  here.\n\n   \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftony-aw%2Fbroadcast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftony-aw%2Fbroadcast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftony-aw%2Fbroadcast/lists"}