{"id":14068294,"url":"https://github.com/mkearney/attrbl","last_synced_at":"2026-05-21T16:38:36.536Z","repository":{"id":124078164,"uuid":"121050454","full_name":"mkearney/attrbl","owner":"mkearney","description":"A tidy approach to attributes","archived":false,"fork":false,"pushed_at":"2018-02-22T00:06:12.000Z","size":24,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-15T09:43:39.510Z","etag":null,"topics":["attr","attributes","dataframes","mkearney-r-package","r","rstats","tibble","tidy","tidy-data","tidyverse"],"latest_commit_sha":null,"homepage":"","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mkearney.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-02-10T20:14:34.000Z","updated_at":"2020-09-30T23:28:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"5e2ff142-0e68-4a0f-9040-904faead3d5a","html_url":"https://github.com/mkearney/attrbl","commit_stats":{"total_commits":17,"total_committers":1,"mean_commits":17.0,"dds":0.0,"last_synced_commit":"87b6c2007d9f3432783eb06e990f59823a66bd13"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkearney%2Fattrbl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkearney%2Fattrbl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkearney%2Fattrbl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkearney%2Fattrbl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mkearney","download_url":"https://codeload.github.com/mkearney/attrbl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241940541,"owners_count":20045878,"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","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":["attr","attributes","dataframes","mkearney-r-package","r","rstats","tibble","tidy","tidy-data","tidyverse"],"created_at":"2024-08-13T07:06:04.770Z","updated_at":"2025-12-02T17:02:29.671Z","avatar_url":"https://github.com/mkearney.png","language":"R","funding_links":[],"categories":["R"],"sub_categories":[],"readme":"---\ntitle: \"attrbl\"\noutput: github_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE, collapse = FALSE, comment = \"#\u003e\")\nlibrary(attrbl)\nlibrary(magrittr)\n```\n\nA tibble-like package for working with attributes and data frames.\n\n***Warning: this package is in early development***\n\n## Install\n\nInstall the dev version from Github\n\n```{r, eval = FALSE}\nif (!requireNamespace(\"devtools\", quietly = TRUE)) {\n  install.packages(\"devtools\")\n}\ndevtools::install_github(\"mkearney/attrbl\")\n```\n\n## Use case\n\nLet's say you have a list of two data frames. And each data frame contains a data frame attribute \"users\" with around 100 observations.\n\n```{r, cache=TRUE}\n## tweets data with users data attribute\nrts \u003c- list(\n  rtweet::search_tweets(\"statistics\", verbose = FALSE),\n  rtweet::search_tweets(\"data science\", verbose = FALSE))\n\n## each object contains \"users\" data attribute with around 100 rows\nrts %\u003e%\n  lapply(rtweet::users_data) %\u003e%\n  lapply(nrow)\n```\n\nWhen you bind the data frames using `do.call(..., rbind)`, it returns a \"users\" attribute. But it only has around 100 rows (it should be closer to 200). It completely **drops** the second \"users\" attribute!\n\n```{r}\n## base R's method\nrts %\u003e%\n  do.call(\"rbind\", .) %\u003e%\n  attr(\"users\") %\u003e%\n  nrow()\n```\n\nWhen you bind the data frames using `dplyr::bind_rows(...)`, it **doesn't return** a \"users\" attribute at all!\n\n```{r}\n## dplyr's bind_rows method\nrts %\u003e%\n  dplyr::bind_rows() %\u003e%\n  attr(\"users\")\n```\n\nBut when you bind the data frames using `attrbl::do_call_rbind(...)`, it not only **keeps** all \"users\" attributes. It binds them together for you!\n\n```{r}\n## attrbl's do_call_rbind method\nrts %\u003e%\n  lapply(as_attrbl) %\u003e%\n  do_call_rbind() %\u003e%\n  attr(\"users\") %\u003e%\n  nrow()\n```\n\n## Usage\n\n### Bind data frames without losing attributes\n\nWhen a `data.frame` is merged with `dplyr::bind_rows(...)`, it **loses** its attribute(s).\n\n```{r}\n## list of data frames\nmtcars2 \u003c- list(mtcars, mtcars)\n\n## dplyr method\nmtcars2 %\u003e%\n  dplyr::bind_rows() %\u003e%\n  attr(\"row.names\")\n```\n\nWhen an `attrbl` is merged with `attrbl::do_call_rbind`, it **keeps** its attribute(s).\n\n```{r}\n## attrbl method\nmtcars2 %\u003e%\n  lapply(as_attrbl) %\u003e%\n  do_call_rbind() %\u003e%\n  attr(\"row.names\")\n```\n\n### Select attributes with `atselect`\n\nUse `atselect` to select attributes the tidy way (no quotes required).\n\n```{r}\natselect(mtcars, row.names, class)\n```\n\n### Add attributes with `add_attr`\n\nUse `add_attr` to add one or more attributes to a data frame.\n\n```{r}\nmtcars %\u003e%\n  add_attr(seed = quote(set.seed(1234)), timestamp = Sys.time()) %\u003e%\n  attributes()\n```\n\n\u003c!--\n## Tidy evaluation reading materials\n\n+ [Slides: Tidy Eval Hygienic FEXPRS](https://www.r-project.org/dsc/2017/slides/tidyeval-hygienic-fexprs.pdf)\n+ [Thesis](https://web.wpi.edu/Pubs/ETD/Available/etd-090110-124904/unrestricted/jshutt.pdf)\n+ [Blog post](http://www.onceupondata.com/2017/08/12/my-first-steps-into-the-world-of-tidyeval/)\n\n--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkearney%2Fattrbl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkearney%2Fattrbl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkearney%2Fattrbl/lists"}