├── .Rbuildignore ├── .gitignore ├── .travis.yml ├── DESCRIPTION ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── arrange.R ├── bind_cols.R ├── bind_rows.R ├── decr.R ├── filter.R ├── group.R ├── join.R ├── mutate.R ├── n_obs.R ├── print.R ├── pull.R ├── repos.R ├── select.R ├── slice.R ├── summarise.R ├── tabsort.R ├── tbl.R ├── tbl_frame.R ├── tbltools-package.R ├── utils-pipe.R └── utils.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── codecov.yml ├── cran-comments.md ├── docs ├── CNAME ├── LICENSE.html ├── authors.html ├── docsearch.css ├── docsearch.js ├── extra.css ├── index.html ├── link.svg ├── logo.png ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── arrange_data.html │ ├── arrange_rows.html │ ├── as_tbl.html │ ├── as_tbl_data.html │ ├── bind_cols_data.html │ ├── bind_rows_data.html │ ├── decr.html │ ├── do_call_rbind.html │ ├── env_tbls.html │ ├── figures │ │ └── logo.png │ ├── filter_data.html │ ├── filter_rows.html │ ├── group_by_data.html │ ├── group_by_data_data.html │ ├── group_by_data_groups.html │ ├── group_data.html │ ├── group_data_data.html │ ├── group_data_groups.html │ ├── index.html │ ├── join.html │ ├── mutate_data.html │ ├── mutate_if_data.html │ ├── n_obs.html │ ├── pipe.html │ ├── print.tbl_data.html │ ├── pull_data.html │ ├── repos_back.html │ ├── repos_front.html │ ├── select_cols.html │ ├── select_data.html │ ├── slice_data.html │ ├── summarise_data.html │ ├── tabsort.html │ ├── tbl_data.html │ ├── tbl_data_frame.html │ ├── tbltools-package.html │ ├── tidyselector.html │ └── ungroup_data.html └── sitemap.xml ├── man ├── arrange_data.Rd ├── as_tbl_data.Rd ├── bind_cols_data.Rd ├── bind_rows_data.Rd ├── decr.Rd ├── env_tbls.Rd ├── figures │ └── logo.png ├── filter_data.Rd ├── group_by_data.Rd ├── group_by_data_data.Rd ├── group_by_data_groups.Rd ├── join.Rd ├── mutate_data.Rd ├── mutate_if_data.Rd ├── n_obs.Rd ├── pipe.Rd ├── print.tbl_data.Rd ├── pull_data.Rd ├── repos_back.Rd ├── repos_front.Rd ├── select_data.Rd ├── slice_data.Rd ├── summarise_data.Rd ├── tabsort.Rd ├── tbl_data.Rd ├── tbl_data_frame.Rd ├── tbltools-package.Rd └── ungroup_data.Rd ├── pkgdown └── extra.css ├── tbltools.Rproj └── tests ├── testthat.R └── testthat ├── test-bind.R ├── test-group.R ├── test-joins.R ├── test-mutate.R ├── test-print.R ├── test-select.R ├── test-tbl.R └── test-tbl_frame.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^make\.R$ 2 | ^CRAN-RELEASE$ 3 | ^cran-comments\.md$ 4 | ^codecov\.yml$ 5 | ^\.travis\.yml$ 6 | ^LICENSE\.md$ 7 | ^README\.Rmd$ 8 | ^.*\.Rproj$ 9 | ^\.Rproj\.user$ 10 | ^docs$ 11 | ^_pkgdown\.yml$ 12 | ^pkgdown*$ 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rhistory 2 | .RData 3 | .Rproj.user 4 | .DS_Store 5 | CRAN-RELEASE 6 | make.R 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | after_success: 7 | - Rscript -e 'covr::codecov()' 8 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: tbltools 2 | Title: Tools for Working with Tibbles 3 | Version: 0.1.0 4 | Authors@R: 5 | person(given = "Michael W.", 6 | family = "Kearney", 7 | role = c("aut", "cre"), 8 | email = "kearneymw@missouri.edu", 9 | comment = c(ORCID = "0000-0002-0730-4694")) 10 | Description: Tools for working with tibbles, or data.frame-like objects 11 | generated by the 'tibble' package . Functions 12 | assist in converting objects to tibbles and creating frequency tables. 13 | License: GPL-3 14 | Encoding: UTF-8 15 | LazyData: true 16 | Imports: 17 | magrittr 18 | Suggests: 19 | testthat, 20 | covr 21 | RoxygenNote: 6.1.1 22 | URL: https://github.com/mkearney/tbltools 23 | BugReports: https://github.com/mkearney/tbltools/issues 24 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(arrange_data,default) 4 | S3method(as_tbl_data,data.frame) 5 | S3method(as_tbl_data,default) 6 | S3method(as_tbl_data,list) 7 | S3method(as_tbl_data,matrix) 8 | S3method(as_tbl_data,table) 9 | S3method(as_tbl_data,tbl_data) 10 | S3method(filter_data,default) 11 | S3method(group_by_data,default) 12 | S3method(group_by_data,grouped_data) 13 | S3method(mutate_data,default) 14 | S3method(mutate_data,grouped_data) 15 | S3method(mutate_if_data,default) 16 | S3method(mutate_if_data,grouped_data) 17 | S3method(print,tbl_data) 18 | S3method(pull_data,default) 19 | S3method(select_data,default) 20 | S3method(select_data,grouped_data) 21 | S3method(slice_data,default) 22 | S3method(summarise_data,default) 23 | S3method(summarise_data,grouped_data) 24 | S3method(tabsort,default) 25 | S3method(ungroup_data,default) 26 | export("%>%") 27 | export(arrange_data) 28 | export(as_tbl_data) 29 | export(bind_cols_data) 30 | export(bind_rows_data) 31 | export(decr) 32 | export(env_tbls) 33 | export(filter_data) 34 | export(full_join_data) 35 | export(group_by_data) 36 | export(group_by_data_data) 37 | export(group_by_data_groups) 38 | export(left_join_data) 39 | export(mutate_data) 40 | export(mutate_if_data) 41 | export(n_obs) 42 | export(ntbl) 43 | export(pull_data) 44 | export(repos_back) 45 | export(repos_front) 46 | export(right_join_data) 47 | export(select_data) 48 | export(slice_data) 49 | export(summarise_data) 50 | export(tabsort) 51 | export(tbl_data) 52 | export(tbl_data_frame) 53 | export(ungroup_data) 54 | importFrom(magrittr,"%>%") 55 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # tbltools 0.1.0 2 | 3 | * Added dplyr-like functions `arrange_data()` `filter_data()`, `select_data()`, 4 | `mutate_data()`, `summarise_data()`, `bind_rows_data()`, `full_join_data()`, 5 | `left_join_data()`, `right_join_data()` 6 | 7 | # tbltools 0.0.5 8 | 9 | * tbltools is a lot lighter as rlang, tibble, and tidyselect are no longer dependencies 10 | 11 | # tbltools 0.0.4 12 | 13 | * Added `do_call_rbind()` as convenient shortcut for base do.call("rbind", ...) that will also fill in missing columns with missing values of appropriate class 14 | * Added non-standard evaluation functionality to `filter_rows()` 15 | 16 | # tbltools 0.0.3 17 | 18 | * Added `filter_rows()` and `arrange_rows()` methods as convenient shortcuts 19 | 20 | # tbltools 0.0.2 21 | 22 | * Added a `NEWS.md` file to track changes to the package. 23 | -------------------------------------------------------------------------------- /R/arrange.R: -------------------------------------------------------------------------------- 1 | #' Arrange rows 2 | #' 3 | #' Arrange rows via descending or ascending column values 4 | #' 5 | #' @param .data data frame 6 | #' @param ... One or more unquoted names of columns on which to arrange the rows. If none 7 | #' are supplied, the data are returned as is. By default, ordering is done in ascending 8 | #' order. To orer in descending order, use \code{\link{decr}} on desired variable(s). 9 | #' @return Rearranged data frame 10 | #' @examples 11 | #' 12 | #' ## data frame to arrange 13 | #' dat <- data.frame( 14 | #' a = c(rep("a", 3), rep("b", 3), rep("c", 4)), 15 | #' b = c( 3, 3, 2, 8, 8, 1, 5, 5, 5, 9), 16 | #' c = c(-1, 0, 0, -5, 0, 2, -2, -4, 1, 0), 17 | #' stringsAsFactors = FALSE 18 | #' ) 19 | #' 20 | #' ## arrange by one column 21 | #' arrange_data(dat, a) 22 | #' 23 | #' ## arrange by multiple columns 24 | #' arrange_data(dat, decr(a), b, c) 25 | #' 26 | #' @export 27 | arrange_data <- function(.data, ...) { 28 | UseMethod("arrange_data") 29 | } 30 | 31 | #' @export 32 | arrange_data.default <- function(.data, ...) { 33 | dots <- capture_dots(...) 34 | 35 | ## if no columns supplied, return .data 36 | if (length(dots) == 0) { 37 | return(.data) 38 | } 39 | 40 | ## order the data with relevant columns selected 41 | .order_data <- select_data(.data, ...) 42 | row_names <- do.call(base::order, c(as.list(.order_data))) 43 | 44 | ## reorganize using ordered row_names 45 | .data <- .data[row_names, ] 46 | 47 | ## reset row names 48 | row.names(.data) <- NULL 49 | 50 | ## return data 51 | .data 52 | } 53 | 54 | -------------------------------------------------------------------------------- /R/bind_cols.R: -------------------------------------------------------------------------------- 1 | #' Bind columns 2 | #' 3 | #' Bind together the columns of two or more data frames. 4 | #' 5 | #' @param ... Data frames 6 | #' @return Single data frame with combined columns 7 | #' @export 8 | bind_cols_data <- function(...) { 9 | dots <- peel_list_alist(list(...)) 10 | as_tbl_data(do.call(base::cbind, dots, quote = FALSE)) 11 | } 12 | -------------------------------------------------------------------------------- /R/bind_rows.R: -------------------------------------------------------------------------------- 1 | 2 | #' Bind rows 3 | #' 4 | #' Convenient wrapper around \code{\link[base]{do.call}("rbind", ...)} that 5 | #' (a) sets the 'quote' argument to TRUE and (b) fills data frames with missing 6 | #' columns with NAs of the appropriate class. 7 | #' 8 | #' @param ... Input data frames or list of data frames 9 | #' @param fill Logical indicating whether to fill missing columns in data frames 10 | #' with missing values. 11 | #' @return The list collapsed into a single data frame 12 | #' @examples 13 | #' 14 | #' ## list of data frames with inconsistent columns 15 | #' x <- as_tbl_data(mtcars[1:3, ]) 16 | #' xx <- x 17 | #' xx$y <- "a" 18 | #' l <- list(x, xx, mtcars) 19 | #' 20 | #' ## bind rows and fill missing columns with NAs 21 | #' bind_rows_data(l, fill = TRUE) 22 | #' 23 | #' @export 24 | bind_rows_data <- function(..., fill = FALSE) { 25 | x <- peel_list_alist(list(...)) 26 | if (length(x) == 1L) return(x[[1]]) 27 | if (fill && !same_names(x)) { 28 | cls <- lapply(x, function(.x) { 29 | tbl_data( 30 | name = names(.x), 31 | class = lapply(.x, class) 32 | ) 33 | }) 34 | cls <- c(as.list(cls), stringsAsFactors = FALSE, 35 | deparse.level = 0, make.row.names = FALSE) 36 | cls <- do.call(base::rbind, cls, quote = FALSE) 37 | cls <- cls[!duplicated(cls$name), , drop = FALSE] 38 | 39 | for (i in seq_along(x)) { 40 | if (any(!cls$name %in% names(x[[i]]))) { 41 | not_in_x <- which(!cls$name %in% names(x[[i]])) 42 | for (j in not_in_x) { 43 | x[[i]][[cls$name[j]]] <- NA 44 | class(x[[i]][[cls$name[j]]]) <- cls$class[[j]] 45 | } 46 | } 47 | } 48 | } 49 | x <- c(as.list(x), stringsAsFactors = FALSE, 50 | deparse.level = 0, make.row.names = FALSE) 51 | as_tbl_data(do.call(base::rbind, x, quote = FALSE)) 52 | } 53 | 54 | same_names <- function(x) { 55 | if (n_uq(lengths(x)) != 1L) { 56 | return(FALSE) 57 | } 58 | nms <- uq_names(x) 59 | all(sapply(x, function(.x) all(nms %in% names(.x)))) 60 | } 61 | 62 | uq_names <- function(x) unique(unlist(lapply(x, names), use.names = FALSE)) 63 | -------------------------------------------------------------------------------- /R/decr.R: -------------------------------------------------------------------------------- 1 | 2 | #' Decreasing order 3 | #' 4 | #' Arranges vector in descending order 5 | #' 6 | #' @param x Input vector 7 | #' @examples 8 | #' ## decreasing 1:10 9 | #' decr(1:10) 10 | #' @return Reordered vector 11 | #' @export 12 | decr <- function(x) -xtfrm(x) 13 | 14 | -------------------------------------------------------------------------------- /R/filter.R: -------------------------------------------------------------------------------- 1 | #' Filter rows 2 | #' 3 | #' Filter rows via integer/numeric position or logical vector 4 | #' 5 | #' @param .data Data frame or two dimensional array 6 | #' @param ... Each argument/expression should should evaluate and reduce down to 7 | #' an integer (row number) or logical vector. The filter will keep all row 8 | #' numbers that appear in all evaluated expressions (commas are the equivalent 9 | #' to \code{&}. Row numbers higher than what exists in x will be ignored. Any 10 | #' numeric vector must be either all positive or all negative (excludes). This 11 | #' function uses non-standard evaluation–users can refer to column names 12 | #' without quotations. 13 | #' @return Sliced/filtered data frame 14 | #' @examples 15 | #' set.seed(12) 16 | #' d <- data.frame( 17 | #' mpg = rnorm(100, 25, 3), 18 | #' gear = sample(3:6, 100, replace = TRUE), 19 | #' vs = sample(0:1, 100, replace = TRUE), 20 | #' stringsAsFactors = FALSE 21 | #' ) 22 | #' 23 | #' filter_data(d, mpg > 30) 24 | #' filter_data(d, !mpg < 30) 25 | #' filter_data(d, mpg > 30, !mpg < 30) 26 | #' filter_data(d, mpg > 30, gear == 4) 27 | #' filter_data(d, mpg > 30 | gear == 4, vs == 1) 28 | #' 29 | #' @export 30 | filter_data <- function(.data, ...) UseMethod("filter_data") 31 | 32 | #' @export 33 | filter_data.default <- function(.data, ...) { 34 | if (length(dim(.data)) != 2) { 35 | stop("filter_data method requires two-dimensional object", call. = FALSE) 36 | } 37 | dots <- capture_dots(...) 38 | e <- call_env() 39 | i <- lapply(dots, function(.x) { 40 | o <- eval(.x, .data, e) 41 | if (is.logical(o)) o <- which(o) 42 | o 43 | }) 44 | it <- table(unlist(i)) 45 | i <- as.integer(names(it[it == length(i)])) 46 | if (length(i) == 0) return(.data) 47 | if (is.logical(i)) i <- which(i) 48 | i <- i[i <= nrow(.data)] 49 | .data <- `[`(.data, i, ) 50 | row.names(.data) <- NULL 51 | .data 52 | } 53 | -------------------------------------------------------------------------------- /R/group.R: -------------------------------------------------------------------------------- 1 | 2 | #' Group data 3 | #' 4 | #' Indicate grouping variables in data frame 5 | #' 6 | #' @param .data Data frame 7 | #' @param ... Unquoted (non-standard evaluation) name(s) of group variable(s). 8 | #' @examples 9 | #' d <- data.frame(a = c("a", "b", "c"), b = 1:3, stringsAsFactors = FALSE) 10 | #' group_by_data(d, a) 11 | #' @return A data frame with groups attribute 12 | #' @export 13 | group_by_data <- function(.data, ...) { 14 | UseMethod("group_by_data") 15 | } 16 | 17 | #' @export 18 | group_by_data.grouped_data <- function(.data, ...) { 19 | .data <- ungroup_data(.data) 20 | group_by_data(.data, ...) 21 | } 22 | 23 | #' @export 24 | group_by_data.default <- function(.data, ...) { 25 | g <- select_data(.data, ...) 26 | group_by_data_(.data, g) 27 | } 28 | 29 | group_by_data_str <- function(.data, groups) { 30 | g <- .data[groups] 31 | group_by_data_(.data, g) 32 | } 33 | 34 | group_by_data_ <- function(.data, g) { 35 | is_fct <- vapply(g, is.factor, FUN.VALUE = logical(1), USE.NAMES = FALSE) 36 | attr(.data, ".row_num") <- as.integer(interaction( 37 | lapply(g[!is_fct], function(.x) { 38 | if (is.factor(.x)) { 39 | return(.x) 40 | } 41 | .x <- as.character(.x) 42 | factor(.x, levels = unique(.x)) 43 | }), 44 | drop = TRUE 45 | )) 46 | attr(.data, "group_names") <- names(g) 47 | structure( 48 | .data, 49 | names = names(.data), 50 | row.names = .set_row_names(length(.data[[1]])), 51 | class = c("grouped_data", "tbl_data", "tbl_df", "tbl", "data.frame") 52 | ) 53 | } 54 | 55 | 56 | group_by_data_gd <- function(.data, gd) { 57 | attr(.data, "groups") <- gd 58 | structure( 59 | .data, 60 | names = names(.data), 61 | row.names = .set_row_names(length(.data[[1]])), 62 | class = c("grouped_data", "tbl_data", "tbl_df", "tbl", "data.frame") 63 | ) 64 | } 65 | 66 | #' Ungroup data 67 | #' 68 | #' Ungroups grouped data 69 | #' 70 | #' @param .data Grouped data 71 | #' @return Data grame without groups attribute 72 | #' @export 73 | ungroup_data <- function(.data) { 74 | UseMethod("ungroup_data") 75 | } 76 | 77 | #' @export 78 | ungroup_data.default <- function(.data) { 79 | structure( 80 | .data, 81 | names = names(.data), 82 | row.names = .set_row_names(length(.data[[1]])), 83 | class = c("tbl_data", "tbl_df", "tbl", "data.frame") 84 | ) 85 | } 86 | 87 | #' Groups in grouped data 88 | #' 89 | #' Returns grouping variable names of grouped data 90 | #' 91 | #' @param x Grouped data frame 92 | #' @return Names of grouping variables 93 | #' @export 94 | group_by_data_groups <- function(x) attr(x, "group_names") 95 | 96 | #' Group row numbers in grouped data 97 | #' 98 | #' Returns row numbers for each group in grouped data 99 | #' 100 | #' @param x Groupted data frame 101 | #' @return List of row numbers for each group 102 | #' @export 103 | group_by_data_data <- function(x) attr(x, ".row_num") 104 | 105 | -------------------------------------------------------------------------------- /R/join.R: -------------------------------------------------------------------------------- 1 | 2 | #' Joins 3 | #' 4 | #' Full join: join two data frames preserving all possible information 5 | #' 6 | #' @param x Left or first data frame 7 | #' @param y Right or second data frame 8 | #' @param by Name (character) of variable(s) on which to join 9 | #' @return Joined (merged) data frame 10 | #' @rdname join 11 | #' @examples 12 | #' 13 | #' d1 <- tbl_data( 14 | #' x = 1:10, 15 | #' y = rnorm(10), 16 | #' z = letters[1:10] 17 | #' ) 18 | #' d2 <- tbl_data( 19 | #' x = sample(1:10, 20, replace = TRUE), 20 | #' y2 = rnorm(20) 21 | #' ) 22 | #' 23 | #' ## left join 24 | #' left_join_data(d1, d2) 25 | #' 26 | #' ## right join 27 | #' right_join_data(d1, d2) 28 | #' 29 | #' ## full join 30 | #' full_join_data(d1, d2) 31 | #' 32 | #' @export 33 | full_join_data <- function(x, y, by = NULL) { 34 | if (is.null(by)) { 35 | by <- intersect(names(x), names(y)) 36 | message("Joining, by = ", paste0('"', paste0(by, collapse = '", "'), '"')) 37 | } 38 | nms <- unique(c(names(x), names(y))) 39 | nms <- unlist(lapply(nms, function(.x) c(.x, paste0(.x, ".x"), paste0(.x, ".y")))) 40 | x$merge.x___x.merge <- seq_len(nrow(x)) 41 | y$merge.y___y.merge <- seq_len(nrow(y)) 42 | m <- merge(x, y, by = by, all = TRUE, sort = FALSE) 43 | o <- do.call( 44 | base::order, 45 | c(as.list(m[, c("merge.x___x.merge", "merge.y___y.merge")]), 46 | decreasing = FALSE) 47 | ) 48 | m <- m[o, ] 49 | row.names(m) <- NULL 50 | m$merge.x___x.merge <- NULL 51 | m$merge.y___y.merge <- NULL 52 | o <- order(match(names(m), nms)) 53 | as_tbl_data(m)[, o] 54 | } 55 | 56 | #' Left join 57 | #' 58 | #' Left join: Join two data frames by matching the second (right) data frame to 59 | #' the left (first) such that the structure of the first (left) data frame is 60 | #' preserved 61 | #' 62 | #' @inheritParams full_join 63 | #' @rdname join 64 | #' @export 65 | left_join_data <- function(x, y, by = NULL) { 66 | if (is.null(by)) { 67 | by <- intersect(names(x), names(y)) 68 | message("Joining, by = ", paste0('"', paste0(by, collapse = '", "'), '"')) 69 | } 70 | nms <- unique(c(names(x), names(y))) 71 | nms <- unlist(lapply(nms, function(.x) c(.x, paste0(.x, ".x"), paste0(.x, ".y")))) 72 | x$merge.x___x.merge <- seq_len(nrow(x)) 73 | y$merge.y___y.merge <- seq_len(nrow(y)) 74 | m <- merge(x, y, by.x = by, all = FALSE, all.x = TRUE, all.y = FALSE, sort = FALSE) 75 | o <- do.call( 76 | base::order, 77 | c(as.list(m[, c("merge.x___x.merge", "merge.y___y.merge")]), 78 | decreasing = FALSE) 79 | ) 80 | m <- m[o, ] 81 | row.names(m) <- NULL 82 | m$merge.x___x.merge <- NULL 83 | m$merge.y___y.merge <- NULL 84 | o <- order(match(names(m), nms)) 85 | as_tbl_data(m)[, o] 86 | } 87 | 88 | #' Right join 89 | #' 90 | #' Right join: Join two data frames by matching the first (left) data frame to 91 | #' the right (second) such that the structure of the second (right) data frame 92 | #' is preserved 93 | #' 94 | #' @inheritParams full_join 95 | #' @rdname join 96 | #' @export 97 | right_join_data <- function(x, y, by = NULL) { 98 | if (is.null(by)) { 99 | by <- intersect(names(x), names(y)) 100 | message("Joining, by = ", paste0('"', paste0(by, collapse = '", "'), '"')) 101 | } 102 | nms <- unique(c(names(x), names(y))) 103 | nms <- unlist(lapply(nms, function(.x) c(.x, paste0(.x, ".x"), paste0(.x, ".y")))) 104 | x$merge.x___x.merge <- seq_len(nrow(x)) 105 | y$merge.y___y.merge <- seq_len(nrow(y)) 106 | m <- merge(x, y, by.y = by, all = FALSE, all.x = FALSE, all.y = TRUE, sort = FALSE) 107 | o <- do.call( 108 | base::order, 109 | c(as.list(m[, c("merge.y___y.merge", "merge.x___x.merge")]), 110 | decreasing = FALSE) 111 | ) 112 | m <- m[o, ] 113 | row.names(m) <- NULL 114 | m$merge.x___x.merge <- NULL 115 | m$merge.y___y.merge <- NULL 116 | o <- order(match(names(m), nms)) 117 | as_tbl_data(m)[, o] 118 | } 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /R/mutate.R: -------------------------------------------------------------------------------- 1 | #' Mutate data 2 | #' 3 | #' Wrangle data by adding or transforming columns 4 | #' 5 | #' @param .data Data frame 6 | #' @param ... One or more expressions using non-standard evaluation designed 7 | #' to return a column of values. These should be named variables. Any names 8 | #' already found in the input data will override those input data frame columns 9 | #' @return Mutated data frame 10 | #' @family mutate 11 | #' @export 12 | mutate_data <- function(.data, ...) { 13 | UseMethod("mutate_data") 14 | } 15 | 16 | #' @export 17 | mutate_data.default <- function(.data, ...) { 18 | dots <- pretty_dots(...) 19 | vars <- names(dots) 20 | e <- call_env() 21 | for (i in seq_along(vars)) { 22 | .data[[vars[i]]] <- eval(dots[[i]], .data, e) 23 | } 24 | .data 25 | } 26 | 27 | #' @export 28 | mutate_data.grouped_data <- function(.data, ...) { 29 | e <- call_env() 30 | dots <- pretty_dots(...) 31 | vars <- names(dots) 32 | group_names <- attr(.data, "group_names") 33 | .row_num <- attr(.data, ".row_num") 34 | .data <- lapply(split_groups(.data), 35 | mutate_data_default, 36 | group_names, vars, dots, e) 37 | .data <- bind_rows_data(.data, fill = FALSE) 38 | group_by_data_str(.data, group_names) 39 | } 40 | 41 | mutate_data_default <- function(.data, group_names, vars, dots, e) { 42 | for (i in seq_along(vars)) { 43 | .data[[vars[i]]] <- eval(dots[[i]], .data, e) 44 | } 45 | as_tbl_data(.data) 46 | } 47 | 48 | 49 | 50 | 51 | 52 | #' Mutate certain columns 53 | #' 54 | #' Wrangle only columns that pass a logical test 55 | #' 56 | #' @param .data Input data frame 57 | #' @param .predicate Function applied to each column evaluating to a logical 58 | #' @param .f Function applied to each .predicate-passing column. Can be written 59 | #' in the formula \code{~ .x} format. 60 | #' @return Data frame with .predicate-passing columns mutated. 61 | #' @family mutate 62 | #' @export 63 | mutate_if_data <- function(.data, .predicate, .f) { 64 | UseMethod("mutate_if_data") 65 | } 66 | 67 | 68 | is_lang <- function(x) identical(typeof(x), "language") 69 | 70 | #' @export 71 | mutate_if_data.default <- function(.data, .predicate, .f) { 72 | ## .predicate 73 | if (is_lang(.predicate)) { 74 | e <- call_env() 75 | .predicate <- eval(.predicate, envir = e)[[2]] 76 | .col <- vapply(.data, 77 | function(.x) eval(.predicate, list(.x = .x), e), 78 | FUN.VALUE = logical(1), 79 | USE.NAMES = FALSE 80 | ) 81 | } else { 82 | .col <- vapply(.data, .predicate, logical(1), USE.NAMES = FALSE) 83 | } 84 | ## function 85 | if (is_lang(.f)) { 86 | e <- call_env() 87 | .f <- eval(.f, envir = e)[[2]] 88 | .data[.col] <- lapply(.data[.col], function(.x) eval(.f, list(.x = .x), e)) 89 | } else { 90 | .data[.col] <- lapply(.data[.col], .f) 91 | } 92 | .data 93 | } 94 | 95 | #' @export 96 | mutate_if_data.grouped_data <- function(.data, .predicate, .f) { 97 | e <- call_env() 98 | ## .predicate 99 | if (is_lang(.predicate)) { 100 | .predicate <- eval(.predicate, envir = e)[[2]] 101 | .col <- vapply(.data, 102 | function(.x) eval(.predicate, list(.x = .x), e), 103 | FUN.VALUE = logical(1), 104 | USE.NAMES = FALSE 105 | ) 106 | } else { 107 | .col <- vapply(.data, .predicate, logical(1), USE.NAMES = FALSE) 108 | } 109 | group_names <- attr(.data, "group_names") 110 | .row_num <- attr(.data, ".row_num") 111 | .data <- lapply(split_groups(.data), mutate_if_data_default, .col, .f, e) 112 | .data <- bind_rows_data(.data, fill = FALSE) 113 | group_by_data_str(.data, group_names) 114 | } 115 | 116 | mutate_if_data_default <- function(.data, .col, .f, e) { 117 | if (is_lang(.f)) { 118 | e <- call_env() 119 | .f <- eval(.f, envir = e)[[2]] 120 | .data[.col] <- lapply(.data[.col], function(.x) eval(.f, list(.x = .x), e)) 121 | } else { 122 | .data[.col] <- lapply(.data[.col], .f) 123 | } 124 | .data 125 | } 126 | -------------------------------------------------------------------------------- /R/n_obs.R: -------------------------------------------------------------------------------- 1 | #' Number of observersations 2 | #' 3 | #' Returns number of observations in group (if no group then number of obs 4 | #' in data frame) 5 | #' 6 | #' @return Number of observations in group 7 | #' @export 8 | n_obs <- function() { 9 | if (identical(call_env(), base::.GlobalEnv)) { 10 | stop("`n_obs()` should not be used in global environment", call. = FALSE) 11 | } 12 | vars <- ls(all.names = TRUE, envir = call_env(), sorted = TRUE) 13 | if (length(vars) == 0) return(0) 14 | lens <- integer(length(vars)) 15 | for (i in seq_along(vars)) { 16 | lens[i] <- length(get(vars[i], envir = call_env())) 17 | } 18 | max(lens) 19 | } 20 | -------------------------------------------------------------------------------- /R/print.R: -------------------------------------------------------------------------------- 1 | #' Print tbl_data 2 | #' 3 | #' Method for printing pseduo tibble 4 | #' 5 | #' @param x Input object 6 | #' @param n Maximum number of rows to print, if NULL (default) defaults to 7 | #' \code{getOption("tbltools.print_n", 10)}. 8 | #' 9 | #' @param ... Other args passed to tibble or data.frame print. 10 | #' @export 11 | print.tbl_data <- function(x, n = NULL, ...) { 12 | if (is.null(n)) { 13 | n <- getOption("tbltools.print_n", 10) 14 | } 15 | ## if tibble is installed and loaded, print as tbl_df 16 | if (getOption("tbltools.print_tibble", TRUE) && isNamespaceLoaded("tibble")) { 17 | x <- as_tibble_tibble(x) 18 | print(x, n = n, ...) 19 | 20 | ## otherwise print as pseudo tibble 21 | } else { 22 | ## get dimensions 23 | n_rows <- nrow(x) 24 | nce <- if (n < 20) ceiling(1.9 * n) else n 25 | 26 | ## if rows are cutoff, make printing note 27 | if (nrow(x) > nce) { 28 | trunc_rows <- "*" 29 | ll <- sprintf("*%s row(s) not printed", 30 | formatC(nrow(x) - n, big.mark = ",", digits = 15, format = "d", width = -1)) 31 | } else { 32 | trunc_rows <- "" 33 | ll <- "" 34 | } 35 | n_cols <- ncol(x) 36 | x <- head_data(as_data_frame_data_frame(x), n) 37 | 38 | ## convert to ASCII for consistent printing 39 | is_chr <- vapply(x, function(.x) 40 | is.character(.x) || is.factor(.x), 41 | logical(1), USE.NAMES = FALSE) 42 | x[is_chr] <- lapply(x[is_chr], iconv, to = "ASCII", sub = "byte") 43 | 44 | ## get printing width 45 | w <- getOption("width", 80) 46 | 47 | ## column widths 48 | col_widths <- vapply(seq_len(ncol(x)), 49 | function(i) { 50 | .x <- as.character(c(names(x)[i], x[[i]])) 51 | max(nchar(.x), na.rm = TRUE) 52 | }, 53 | integer(1), USE.NAMES = FALSE) 54 | 55 | ## if data needs truncating... 56 | if (sum(col_widths) > w) { 57 | ## max trunc long char and poxi columns and var names 58 | nms <- substr_dots(names(x), stop = 22) 59 | nms[duplicated(nms)] <- names(x)[duplicated(nms)] 60 | names(x) <- nms 61 | x[is_chr] <- lapply(x[is_chr], substr_dots, stop = 22) 62 | is_psx <- vapply( 63 | x, inherits, c("POSIXct", "POSIXt"), 64 | FUN.VALUE = logical(1), 65 | USE.NAMES = FALSE 66 | ) 67 | x[is_psx] <- lapply(x[is_psx], substr_dots, stop = 22) 68 | } 69 | 70 | ## max number of chars per column 71 | chars <- vapply( 72 | seq_len(ncol(x)), 73 | function(i) 2 + max(nchar(c(names(x)[i], x[[i]])), na.rm = TRUE), 74 | numeric(1), 75 | USE.NAMES = FALSE 76 | ) 77 | 78 | ## determine columns to print 79 | chars[1] <- chars[1] + 1 80 | kp <- which(cumsum(chars) < w) 81 | 82 | if (length(kp) < n_cols) { 83 | trunc_cols <- "\u002b" 84 | if (!identical(ll, "")) { 85 | ll <- paste0(ll, sprintf("; \u002b%s column(s) not printed", 86 | formatC(n_cols - length(kp), big.mark = ",", 87 | digits = 15, format = "d", width = -1))) 88 | } else { 89 | ll <- sprintf("\u002b%s column(s) not printed", 90 | formatC(n_cols - length(kp), big.mark = ",", 91 | digits = 15, format = "d", width = -1)) 92 | } 93 | } else { 94 | trunc_cols <- "" 95 | } 96 | ## print top-level info 97 | pcat(gray_text("# A pseudo tibble: ", 98 | formatC(n_rows, big.mark = ",", digits = 15, format = "d", width = -1), 99 | trunc_rows, " x ", 100 | n_cols, trunc_cols)) 101 | ## print data 102 | x <- x[kp] 103 | if ((ncol(x) * nrow(x)) > getOption("max.print", 10000)) { 104 | rn <- getOption("max.print", 10000) / ncol(x) 105 | } else { 106 | rn <- nrow(x) 107 | } 108 | if (n < 10) { 109 | rn <- sprintf("%1d) ", seq_len(rn)) 110 | } else if (n < 100) { 111 | rn <- sprintf("%2d) ", seq_len(rn)) 112 | } else if (n < 1000) { 113 | rn <- sprintf("%3d) ", seq_len(rn)) 114 | } else { 115 | rn <- sprintf("%4d) ", seq_len(rn)) 116 | } 117 | print(x, ..., right = TRUE, row.names = rn) 118 | ## print truncation info 119 | if (!identical(ll, "")) pcat(gray_text(ll)) 120 | } 121 | } 122 | 123 | 124 | head_data <- function(x, n = 10) { 125 | n1.9 <- ceiling(n * 1.9) 126 | if (n > 20) n1.9 <- n 127 | if (nrow(x) > n1.9) { 128 | x <- x[seq_len(n), , drop = FALSE] 129 | } 130 | x 131 | } 132 | 133 | substr_dots <- function(x, stop = 20) { 134 | ## adjust stop depending on extent to which mean char is greater than stop 135 | if (all(is.na(x))) return(x) 136 | x <- as.character(x) 137 | ncs <- nchar(x) 138 | if (mean(ncs, na.rm = TRUE) >= (stop * 5.0)) { 139 | stop <- ceiling(stop * 2.0) 140 | } else if (mean(ncs, na.rm = TRUE) >= (stop * 4.0)) { 141 | stop <- ceiling(stop * 1.7) 142 | } else if (mean(ncs, na.rm = TRUE) >= (stop * 3.0)) { 143 | stop <- ceiling(stop * 1.4) 144 | } else if (mean(ncs, na.rm = TRUE) >= (stop * 2.0)) { 145 | stop <- ceiling(stop * 1.2) 146 | } else { 147 | stop <- ceiling(stop * 0.9) 148 | } 149 | mw <- stop 150 | na <- is.na(x) 151 | s <- strsplit(x[!na], "") 152 | w <- lapply(lengths(s), function(i) rep(1, i)) 153 | o <- rep(NA_character_, length(x)) 154 | o[!na] <- vapply( 155 | seq_along(s), 156 | function(i) { 157 | if (any(cumsum(w[[i]]) >= mw)) { 158 | e <- "\u2026" 159 | } else { 160 | e <- "" 161 | } 162 | paste0(paste0(s[[i]][cumsum(w[[i]]) <= mw], collapse = ""), e) 163 | }, 164 | FUN.VALUE = character(1), 165 | USE.NAMES = FALSE 166 | ) 167 | o 168 | } 169 | -------------------------------------------------------------------------------- /R/pull.R: -------------------------------------------------------------------------------- 1 | #' Pull data 2 | #' 3 | #' Pull (extract) data from a data frame 4 | #' 5 | #' @param .data Input data frame 6 | #' @param ... Unquoted name of column to pull from data frame 7 | #' @return A column pulled from its data frame (inheriting whatever class the 8 | #' column is) 9 | #' @examples 10 | #' 11 | #' ## pull the 'y' variable from the data frame 12 | #' tbl_data(x = rnorm(5), y = letters[1:5]) %>% pull_data(y) 13 | #' 14 | #' @export 15 | pull_data <- function(.data, ...) { 16 | UseMethod("pull_data") 17 | } 18 | 19 | #' @export 20 | pull_data.default <- function(.data, ...) { 21 | eval(capture_dots(...)[[1]], .data, new.env(parent = emptyenv())) 22 | } 23 | -------------------------------------------------------------------------------- /R/repos.R: -------------------------------------------------------------------------------- 1 | 2 | #' move vars to front 3 | #' 4 | #' @param data data frame 5 | #' @param ... columns to move to front 6 | #' @export 7 | #' @examples 8 | #' ## data with row names 9 | #' d <- data.frame(x = rnorm(5), y = rnorm(5), row.names = letters[1:5]) 10 | #' 11 | #' ## move y to front 12 | #' repos_front(d, y) 13 | #' 14 | #' @return Reordered data frame. 15 | repos_front <- function(data, ...) { 16 | re <- select_data(data, ...) 17 | as_tbl_data(cbind(re, data[!names(data) %in% names(re)])) 18 | } 19 | 20 | #' move vars to back 21 | #' 22 | #' @param data data frame 23 | #' @param ... columns to move to back 24 | #' @export 25 | #' @examples 26 | #' ## data with row names 27 | #' d <- data.frame(x = rnorm(5), y = rnorm(5), row.names = letters[1:5]) 28 | #' 29 | #' ## move x to back 30 | #' repos_back(d, x) 31 | #' 32 | #' @return Reordered data frame. 33 | repos_back <- function(data, ...) { 34 | re <- select_data(data, ...) 35 | as_tbl_data(cbind(data[!names(data) %in% names(re)], re)) 36 | } 37 | -------------------------------------------------------------------------------- /R/select.R: -------------------------------------------------------------------------------- 1 | 2 | #' Select columns 3 | #' 4 | #' Select columns with non-standard evaluation 5 | #' 6 | #' @param .data Input data frame 7 | #' @param ... Unquoted names of columns to select 8 | #' @export 9 | #' @return Data frame with select columns 10 | select_data <- function(.data, ...) { 11 | UseMethod("select_data") 12 | } 13 | 14 | #' @export 15 | select_data.default <- function(.data, ...) { 16 | dots <- pretty_dots(...) 17 | if (length(dots) == 0) { 18 | return(.data) 19 | } 20 | e <- call_env() 21 | vars.dots <- names(dots) 22 | vars.data <- sub("^-", "", vars.dots) 23 | if (all(grepl("^-\\S+", vars.dots))) { 24 | .d <- .data 25 | } else { 26 | .d <- list() 27 | } 28 | assign("-", function(x) NULL, envir = e) 29 | on.exit(rm("-", envir = e), add = TRUE) 30 | assign(":", function(lhs, rhs) { 31 | .data_vars <- rev( 32 | ls(all.names = TRUE, sorted = FALSE, envir = as.environment(.data)) 33 | ) 34 | lhs <- deparse(substitute(lhs)) 35 | rhs <- deparse(substitute(rhs)) 36 | kp <- seq.int( 37 | which(.data_vars == lhs), 38 | which(.data_vars == rhs) 39 | ) 40 | .data[kp] 41 | }, envir = e) 42 | on.exit(rm(":", envir = e), add = TRUE) 43 | for (i in seq_along(dots)) { 44 | vd <- vars.data[i] 45 | if (grepl("\\S\\:\\S", vd)) { 46 | vd <- strsplit(vd, ":")[[1]] 47 | vd <- names(.data)[ 48 | seq(which(names(.data) == vd[1]), which(names(.data) == vd[2])) 49 | ] 50 | .d[vd] <- eval(dots[[vars.dots[i]]], .data, e) 51 | } else { 52 | .d[[vd]] <- eval(dots[[vars.dots[i]]], .data, e) 53 | } 54 | } 55 | structure( 56 | .d, 57 | names = names(.d), 58 | row.names = .set_row_names(length(.d[[1]])), 59 | class = c("tbl_data", "tbl_df", "tbl", "data.frame") 60 | ) 61 | } 62 | 63 | 64 | #' @export 65 | select_data.grouped_data <- function(.data, ...) { 66 | ## copy attributes 67 | atts <- attributes(.data) 68 | .data <- as.data.frame(.data) 69 | .data <- select_data(.data, ...) 70 | structure( 71 | .data, 72 | names = names(.data), 73 | row.names = .set_row_names(length(.data[[1]])), 74 | class = c("grouped_data", "tbl_data", "tbl_df", "tbl", "data.frame"), 75 | .row_num = atts$.row_num, 76 | group_names = atts$group_names 77 | ) 78 | } 79 | -------------------------------------------------------------------------------- /R/slice.R: -------------------------------------------------------------------------------- 1 | 2 | #' Slice data 3 | #' 4 | #' Slice data by row number 5 | #' 6 | #' @param .data Input data frame 7 | #' @param ... Expression to evaluate to integer row positions 8 | #' @return .data of evaluated row positions 9 | #' @examples 10 | #' 11 | #' ## data set 12 | #' d <- tbl_data(x = rnorm(10), y = rnorm(10)) 13 | #' 14 | #' ## slice first 4 rows 15 | #' slice_data(d, 1:4) 16 | #' @export 17 | slice_data <- function(.data, ...) { 18 | UseMethod("slice_data") 19 | } 20 | 21 | #' @export 22 | slice_data.default <- function(.data, ...) { 23 | dots <- capture_dots(...) 24 | if (length(dots) > 1L) { 25 | stop("slice onlly accepts one expression", call. = FALSE) 26 | } 27 | rows <- eval(dots[[1]], .data, call_env()) 28 | rows <- as.integer(rows) 29 | .data <- .data[rows, ] 30 | row.names(.data) <- NULL 31 | .data 32 | } 33 | -------------------------------------------------------------------------------- /R/summarise.R: -------------------------------------------------------------------------------- 1 | #' Summarise data 2 | #' 3 | #' Returns a summary-level data frame 4 | #' 5 | #' @param .data Data frame 6 | #' @param ... One or more namecd expressions evaluating with non-standard evaluation 7 | #' to a single summary value. 8 | #' @return A summary-level data frame 9 | #' @export 10 | summarise_data <- function(.data, ...) { 11 | UseMethod("summarise_data") 12 | } 13 | 14 | #' @export 15 | summarise_data.default <- function(.data, ...) { 16 | dots <- pretty_dots(...) 17 | vars <- names(dots) 18 | e <- call_env() 19 | .data <- unclass(.data) 20 | for (i in seq_along(vars)) { 21 | .data[[vars[i]]] <- eval(dots[[i]], .data, e) 22 | } 23 | if (any(lengths(.data[vars]) > 1L)) { 24 | stop("summarise evaluated to more than 1 value") 25 | } 26 | as_tbl_data( 27 | lapply(.data[vars], base::`[`, 1L) 28 | ) 29 | } 30 | 31 | summarise_data_default <- function(.data, group_names, vars, dots, e) { 32 | .data <- unclass(.data) 33 | for (i in vars) { 34 | .data[[i]] <- eval(dots[[i]], .data, e) 35 | } 36 | if (any(lengths(.data[vars]) > 1L)) { 37 | stop("summarise evaluated to more than 1 value") 38 | } 39 | as_tbl_data( 40 | lapply(.data[c(group_names, vars)], base::`[`, 1L) 41 | ) 42 | } 43 | 44 | #' @export 45 | summarise_data.grouped_data <- function(.data, ...) { 46 | dots <- pretty_dots(...) 47 | vars <- names(dots) 48 | e <- call_env() 49 | group_names <- attr(.data, "group_names") 50 | .data <- lapply(split_groups(.data), 51 | summarise_data_default, 52 | group_names, vars, dots, e) 53 | bind_rows_data(.data, fill = FALSE) 54 | } 55 | -------------------------------------------------------------------------------- /R/tabsort.R: -------------------------------------------------------------------------------- 1 | 2 | #' tabsort 3 | #' 4 | #' Returns a sorted (descending) frequency tbl 5 | #' 6 | #' @param .data Data 7 | #' @param ... Unquoted column names of variables to include in table. Default 8 | #' is to use all columns. 9 | #' @param prop Logical indicating whether to include a proportion of total 10 | #' obs column. 11 | #' @param sort Logical indicating whether to sort the returned object. 12 | #' @param na_omit Logical indicating whether to exclude missing. If all 13 | #' responses are missing, a missing value is used as the single category. 14 | #' @return Frequency tbl 15 | #' @examples 16 | #' 17 | #' ## generate example data 18 | #' x <- sample(letters[1:4], 200, replace = TRUE) 19 | #' y <- sample(letters[5:8], 200, replace = TRUE) 20 | #' 21 | #' ## count and sort frequencies for each vector 22 | #' tabsort(x) 23 | #' tabsort(y) 24 | #' 25 | #' ## combine x and y into data frame 26 | #' dat <- data.frame(x, y) 27 | #' 28 | #' ## select columns and create freq table 29 | #' tabsort(dat, x) 30 | #' tabsort(dat, x, y) 31 | #' 32 | #' @export 33 | tabsort <- function(.data, ..., prop = TRUE, na_omit = TRUE, sort = TRUE) { 34 | UseMethod("tabsort") 35 | } 36 | 37 | #' @export 38 | tabsort.default <- function(.data, ..., prop = TRUE, na_omit = TRUE, sort = TRUE) { 39 | ## get names from dots 40 | vars <- names(pretty_dots(...)) 41 | 42 | ## validate 43 | if (!is.logical(prop)) { 44 | stop("'prop' should be logical, indicating whether to return proportions. ", 45 | "If you supplied a vector with the name 'prop' please rename to ", 46 | "something else", call. = FALSE) 47 | } 48 | 49 | ## if only named objects are supplied 50 | if (missing(.data) && length(vars) > 0) { 51 | .data <- data.frame(..., stringsAsFactors = FALSE) 52 | 53 | ## if no data at all is supplied 54 | } else if (missing(.data)) { 55 | stop("must supply data or named object") 56 | 57 | ## if unnamed atomic vector & one or more named objects are supplied 58 | } else if (!is.recursive(.data) && length(vars) > 0) { 59 | 60 | ## rename .data using expression text 61 | assignname <- deparse(substitute(.data)) 62 | .data <- list(.data, ...) 63 | names(.data) <- c(assignname, vars) 64 | 65 | ## if single unnamed vector is supplied 66 | } else if (!is.recursive(.data)) { 67 | .data <- data.frame(x = .data, stringsAsFactors = FALSE) 68 | 69 | ## otherwise use tidy selection of any supplied var names 70 | } else { 71 | .data <- select_data(.data, ...) 72 | } 73 | if (na_omit) { 74 | if (is.data.frame(.data)) { 75 | .data <- na_omit_data.frame(.data) 76 | } else { 77 | .data <- na_omit_list(.data) 78 | } 79 | } 80 | ## check/fix names 81 | if ("n" %in% names(.data)) { 82 | warning("variable n renamed to .n", call. = FALSE) 83 | names(.data)[names(.data) == "n"] <- ".n" 84 | } 85 | if ("prop" %in% names(.data)) { 86 | warning("variable prop renamed to .prop", call. = FALSE) 87 | names(.data)[names(.data) == "prop"] <- ".prop" 88 | } 89 | x <- as_tbl_data(do.call("table", as.list(.data))) 90 | if (prop) { 91 | x$prop <- x$n / sum(x$n, na.rm = TRUE) 92 | } 93 | if (sort) { 94 | x <- x[order(x$n, decreasing = TRUE), ] 95 | } 96 | x 97 | } 98 | 99 | 100 | #' @inheritParams tabsort 101 | #' @rdname tabsort 102 | #' @export 103 | ntbl <- function(.data, ...) { 104 | .data <- select_data(.data, ...) 105 | as_tbl_data(table(.data)) 106 | } 107 | -------------------------------------------------------------------------------- /R/tbl.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' as_tbl_data 4 | #' 5 | #' Converts data objects to tibbles. 6 | #' 7 | #' @param x Data frame or data frame-like input. 8 | #' @param row_names Logical indicating whether to convert non-null row names 9 | #' into the first column. 10 | #' @rdname as_tbl_data 11 | #' @examples 12 | #' ## data with row names 13 | #' d <- data.frame(x = rnorm(5), y = rnorm(5), row.names = letters[1:5]) 14 | #' 15 | #' ## convert to tibble 16 | #' as_tbl_data(d) 17 | #' 18 | #' ## convert to tibble and create row_names variable 19 | #' as_tbl_data(d, row_names = TRUE) 20 | #' 21 | #' @export 22 | as_tbl_data <- function(x, row_names = FALSE) { 23 | UseMethod("as_tbl_data") 24 | } 25 | 26 | #' @export 27 | as_tbl_data.table <- function(x, row_names = FALSE) { 28 | df <- as.data.frame(x, stringsAsFactors = FALSE) 29 | names(df) <- c(names(dimnames(x)), "n") 30 | as_tbl_data.data.frame(df) 31 | } 32 | 33 | #' @export 34 | as_tbl_data.default <- function(x, row_names = FALSE) { 35 | x <- list(x) 36 | structure( 37 | x, 38 | names = names(x), 39 | row.names = .set_row_names(length(x[[1]])), 40 | class = c("tbl_data", "tbl_df", "tbl", "data.frame") 41 | ) 42 | } 43 | 44 | #' @export 45 | as_tbl_data.matrix <- function(x, row_names = FALSE) { 46 | x <- as.data.frame(x, stringsAsFactors = FALSE) 47 | structure( 48 | x, 49 | names = colnames(x), 50 | row.names = .set_row_names(length(x[[1]])), 51 | class = c("tbl_data", "tbl_df", "tbl", "data.frame") 52 | ) 53 | } 54 | 55 | #' @export 56 | as_tbl_data.tbl_data <- function(x, row_names = FALSE) { 57 | x 58 | } 59 | 60 | #' @export 61 | as_tbl_data.data.frame <- function(x, row_names = FALSE) { 62 | if (row_names && !identical(as.character(seq_len(nrow(x))), row.names(x))) { 63 | x$row_names <- row.names(x) 64 | x <- x[c(ncol(x), 1:(ncol(x) - 1))] 65 | row.names(x) <- NULL 66 | } 67 | structure( 68 | x, 69 | names = names(x), 70 | row.names = .set_row_names(length(x[[1]])), 71 | class = c("tbl_data", "tbl_df", "tbl", "data.frame") 72 | ) 73 | } 74 | 75 | #' @export 76 | as_tbl_data.default <- function(x, row_names = FALSE) { 77 | x <- list(x) 78 | structure( 79 | x, 80 | names = names(x), 81 | row.names = .set_row_names(length(x[[1]])), 82 | class = c("tbl_data", "tbl_df", "tbl", "data.frame") 83 | ) 84 | } 85 | 86 | #' @export 87 | as_tbl_data.list <- function(x, row_names = FALSE) { 88 | structure( 89 | x, 90 | names = names(x), 91 | row.names = .set_row_names(length(x[[1]])), 92 | class = c("tbl_data", "tbl_df", "tbl", "data.frame") 93 | ) 94 | } 95 | 96 | #' Convert all data frames in environment into tibbles 97 | #' 98 | #' Converts data frames found in a given environment into tibbles (tbl_df) 99 | #' 100 | #' @param env Name of environment from which data frames should be converted to tibbles. 101 | #' Defaults to global environment. 102 | #' @param row_names Logical indicating whether to create a row_names variable if non-auto 103 | #' row names are found. 104 | #' @return The function will print messages when converting occurs and it will print a final 105 | #' completion message, but otherwise returns nothing. 106 | #' @examples 107 | #' ## data with row names 108 | #' d <- data.frame(x = rnorm(5), y = rnorm(5), row.names = letters[1:5]) 109 | #' 110 | #' ## convert data frames in global environment to tibbles 111 | #' env_tbls() 112 | #' 113 | #' @export 114 | env_tbls <- function(env = globalenv(), row_names = TRUE) { 115 | o <- ls(envir = env, all.names = TRUE) 116 | for (i in seq_along(o)) { 117 | x <- get(o[i], envir = env) 118 | if (is.data.frame(x)) { 119 | x <- as_tbl_data(x, row_names = row_names) 120 | message("Converting ", o[i], " into tbl_df") 121 | assign(o[i], x, envir = env) 122 | } 123 | } 124 | message("Done!") 125 | } 126 | 127 | 128 | #' tbl data 129 | #' 130 | #' Create a tibble data frame 131 | #' 132 | #' @param ... A data frame, vector, or list of values of equal or single-value 133 | #' length–similar to \link[base]{data.frame}. 134 | #' @return An object of class \code{c("tbl_data", "tbl_df", "tbl", "data.frame")} 135 | #' @export 136 | tbl_data <- function(...) { 137 | x <- list(...) 138 | if (length(x) == 1L && is.data.frame(x[[1]])) { 139 | x <- x[[1]] 140 | } 141 | lens <- lengths(x) 142 | if (n_uq(lens) == 2L && 1L %in% lens) { 143 | x[lens == 1L] <- lapply(x[lens == 1L], rep, max(lens)) 144 | } 145 | nms <- names(x) 146 | no_nms <- !nzchar(nms) 147 | nms[no_nms] <- paste0("x", seq_len(sum(no_nms))) 148 | structure( 149 | x, 150 | names = nms, 151 | row.names = .set_row_names(length(x[[1]])), 152 | class = c("tbl_data", "tbl_df", "tbl", "data.frame") 153 | ) 154 | } 155 | -------------------------------------------------------------------------------- /R/tbl_frame.R: -------------------------------------------------------------------------------- 1 | #' Create tbl_data_frame 2 | #' 3 | #' Creates a data frame using non-standard evaluation 4 | #' 5 | #' @param ... Column vectors or expressions that reduce down to desired column vectors of 6 | #' data frame 7 | #' @export 8 | #' @examples 9 | #' 10 | #' ## create data frame with two random variables 11 | #' tbl_data_frame( 12 | #' a = rnorm(10), 13 | #' b = rnorm(10) 14 | #' ) 15 | #' 16 | #' ## create variables calculated using previous variables 17 | #' tbl_data_frame( 18 | #' a = rnorm(10), 19 | #' b = rnorm(10), 20 | #' c = (a + b) / 2, 21 | #' d = a + b + c 22 | #' ) 23 | #' 24 | #' @return A tbl_data data frame 25 | tbl_data_frame <- function(...) { 26 | UseMethod("tbl_data_frame") 27 | } 28 | 29 | #' @export 30 | tbl_data_frame <- function(...) { 31 | dots <- pretty_dots(...) 32 | vars <- names(dots) 33 | e <- call_env() 34 | for (i in vars) { 35 | dots[[i]] <- eval(dots[[i]], dots, e) 36 | } 37 | as_tbl_data(dots) 38 | } 39 | -------------------------------------------------------------------------------- /R/tbltools-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | "_PACKAGE" 3 | 4 | # The following block is used by usethis to automatically manage 5 | # roxygen namespace tags. Modify with care! 6 | ## usethis namespace: start 7 | ## usethis namespace: end 8 | NULL 9 | 10 | .__tt_ns__. <- new.env(parent = emptyenv()) 11 | -------------------------------------------------------------------------------- /R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | NULL 12 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | set_class <- function(x, class) `class<-`(x, class) 2 | 3 | as_tibble_tibble <- function(x) { 4 | set_class(x, c("tbl_df", "tbl", "data.frame")) 5 | } 6 | 7 | as_data_frame_data_frame <- function(x) { 8 | set_class(x, "data.frame") 9 | } 10 | 11 | is_list <- function(x) inherits(x, "list") 12 | 13 | is_list_alist <- function(x) { 14 | is_list(x) && 15 | length(x) == 1 && 16 | is_list(x[[1]]) 17 | } 18 | 19 | is_list_recursive <- function(x) { 20 | is_list(x) && 21 | length(x) == 1 && 22 | is.list(x[[1]]) 23 | } 24 | 25 | peel_list_alist <- function(x) { 26 | if (is_list_alist(x)) { 27 | x <- x[[1]] 28 | } 29 | x 30 | } 31 | 32 | call_env <- function (n = 1) parent.frame(n + 1) 33 | 34 | capture_dots <- function(...) { 35 | eval(substitute(alist(...)), envir = parent.frame()) 36 | } 37 | 38 | expr_names <- function(args) { 39 | vapply( 40 | args, 41 | deparse, 42 | USE.NAMES = FALSE, 43 | FUN.VALUE = character(1) 44 | ) 45 | } 46 | 47 | pretty_dots <- function(...) { 48 | ## capture dots as arg list 49 | dots <- capture_dots(...) 50 | 51 | ## if none provided, return NULL 52 | if (length(dots) == 0) { 53 | return(NULL) 54 | } 55 | 56 | ## if no names, inherit expression text 57 | if (is.null(names(dots))) { 58 | names(dots) <- expr_names(dots) 59 | } 60 | 61 | ## dots names 62 | nms <- names(dots) 63 | 64 | ## if any names missing, assign expression text 65 | if ("" %in% nms) { 66 | names(dots)[nms == ""] <- expr_names(dots[nms == ""]) 67 | } 68 | 69 | dots 70 | } 71 | 72 | pcat <- function(...) { 73 | cat(paste0(c(...), collapse = ""), fill = TRUE) 74 | } 75 | 76 | pcat_lines <- function (...) { 77 | cat(paste0(..., "\n"), sep = "") 78 | } 79 | 80 | gray_text <- function(...) { 81 | dots <- paste0(c(...), collapse = "") 82 | if (interactive()) { 83 | paste0("\033[38;5;243m", dots, "\033[39m") 84 | } else { 85 | dots 86 | } 87 | } 88 | 89 | n_uq <- function(x) NROW(unique(x)) 90 | 91 | all_na <- function(x) all(is.na(unlist(x, use.names = FALSE)) | lengths(x) == 0) 92 | 93 | na_omit_data.frame <- function(x) { 94 | na_rows <- vapply(seq_len(nrow(x)), function(i) 95 | all_na(x[i, ]), logical(1), USE.NAMES = FALSE) 96 | x[!na_rows, , drop = FALSE] 97 | } 98 | 99 | na_omit_list <- function(x) { 100 | na_elems <- vapply(x, all_na, logical(1)) 101 | x[!na_elems] 102 | } 103 | 104 | as_fct <- function(x) { 105 | levels <- unique(x) 106 | x <- as.character(x) 107 | f <- match(x, levels) 108 | levels(f) <- as.character(levels) 109 | class(f) <- "factor" 110 | f 111 | } 112 | 113 | split_default <- function(.data, .i) { 114 | split.default(x = .data, f = as_fct(.i), drop = TRUE) 115 | } 116 | 117 | split_groups <- function(.data) { 118 | .row_num <- attr(.data, ".row_num") 119 | class(.data) <- "data.frame" 120 | attributes(.data) <- attributes(.data)[c("names", "row.names", "class")] 121 | row_nums <- split_default(seq_len(nrow(.data)), .row_num) 122 | lapply( 123 | row_nums, 124 | function(ind) .data[ind, , drop = FALSE] 125 | ) 126 | } 127 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://tbltools.mikewk.com 2 | 3 | authors: 4 | Michael W. Kearney: 5 | href: https://mikewk.com 6 | navbar: 7 | right: 8 | - icon: fa-github fa-lg 9 | href: https://github.com/mkearney/tbltools 10 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | patch: 10 | default: 11 | target: auto 12 | threshold: 1% 13 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * local OS X install, R 3.5.2 3 | * ubuntu 14.04 (on travis-ci), R 3.5.2 4 | * win-builder (devel and release) 5 | 6 | ## R CMD check results 7 | 8 | 0 errors | 0 warnings | 0 notes 9 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | tbltools.mikewk.com 2 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Authors • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 50 | 51 | 52 | 53 | 54 | 55 |
56 |
57 | 100 | 101 | 102 |
103 | 104 |
105 |
106 | 109 | 110 | 116 | 117 |
118 | 119 |
120 | 121 | 122 | 131 |
132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/extra.css: -------------------------------------------------------------------------------- 1 | 2 | @import url("https://fonts.googleapis.com/css?family=Roboto:400,400i,700,700i,900"); 3 | 4 | @import url(https://cdn.rawgit.com/tonsky/FiraCode/1.205/distr/fira_code.css); 5 | 6 | body { 7 | font-family: Roboto, sans-serif; 8 | font-size: 16px; 9 | line-height: 1.5; 10 | font-weight: 400; 11 | margin: .5em auto 5em auto; 12 | } 13 | 14 | h1, h2, h3, h4, .h1, .h2, .h3, .h4 { 15 | font-family: Roboto, sans-serif; 16 | font-weight: 900; 17 | } 18 | 19 | h1 {font-size: 2.1em} 20 | h2 {font-size: 1.8em} 21 | h3 {font-size: 1.6em} 22 | h4 {font-size: 1.3em} 23 | 24 | code { 25 | font-family: "Fira Code", Consolas, Monaco, Menlo, Inconsolata, monospace; 26 | } 27 | 28 | pre { 29 | box-shadow: 30 | rgba(0, 0, 0, 0.1) 0 2px 3px 1px, 31 | rgba(0, 0, 0, 0.1) 0 1px 3px 1px, 32 | rgba(0, 0, 0, 0.2) 0 1px 1px -1px; 33 | font-size: .80em; 34 | margin-left: auto; 35 | width: 98%; 36 | margin-right: auto; 37 | line-height: 1.4em; 38 | font-family: "Fira Code", Consolas, Monaco, Menlo, Inconsolata, monospace; 39 | } 40 | 41 | div.sourceCode { 42 | overflow: visible; 43 | } 44 | 45 | pre.sourceCode { 46 | margin-left: auto; 47 | margin-right: auto; 48 | } 49 | 50 | p { 51 | margin: 1.5em 0; 52 | } 53 | 54 | strong { 55 | font-family: Roboto, sans-serif; 56 | font-weight: 900; 57 | } 58 | 59 | strong code { 60 | font-family: "Fira Code", Consolas, Monaco, Menlo, Inconsolata, monospace; 61 | font-weight: 700; 62 | } 63 | 64 | code span.co, .co { 65 | color: #828f96; 66 | } 67 | 68 | code span.ot, .ot { 69 | color: #ddaa00; 70 | } 71 | 72 | .navbar-default { 73 | box-shadow: 74 | rgba(0, 0, 0, 0.1) 0 2px 3px 1px, 75 | rgba(0, 0, 0, 0.1) 0 1px 3px 1px, 76 | rgba(0, 0, 0, 0.2) 0 1px 1px -1px; 77 | background-color: #f3f3f3; 78 | border-color: #eee; 79 | } 80 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkearney/tbltools/c19a0db8b8eab5fd92ffbb1933de3374e1839cc5/docs/logo.png -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body > .container { 21 | display: flex; 22 | height: 100%; 23 | flex-direction: column; 24 | 25 | padding-top: 60px; 26 | } 27 | 28 | body > .container .row { 29 | flex: 1 0 auto; 30 | } 31 | 32 | footer { 33 | margin-top: 45px; 34 | padding: 35px 0 36px; 35 | border-top: 1px solid #e5e5e5; 36 | color: #666; 37 | display: flex; 38 | flex-shrink: 0; 39 | } 40 | footer p { 41 | margin-bottom: 0; 42 | } 43 | footer div { 44 | flex: 1; 45 | } 46 | footer .pkgdown { 47 | text-align: right; 48 | } 49 | footer p { 50 | margin-bottom: 0; 51 | } 52 | 53 | img.icon { 54 | float: right; 55 | } 56 | 57 | img { 58 | max-width: 100%; 59 | } 60 | 61 | /* Fix bug in bootstrap (only seen in firefox) */ 62 | summary { 63 | display: list-item; 64 | } 65 | 66 | /* Typographic tweaking ---------------------------------*/ 67 | 68 | .contents .page-header { 69 | margin-top: calc(-60px + 1em); 70 | } 71 | 72 | /* Section anchors ---------------------------------*/ 73 | 74 | a.anchor { 75 | margin-left: -30px; 76 | display:inline-block; 77 | width: 30px; 78 | height: 30px; 79 | visibility: hidden; 80 | 81 | background-image: url(./link.svg); 82 | background-repeat: no-repeat; 83 | background-size: 20px 20px; 84 | background-position: center center; 85 | } 86 | 87 | .hasAnchor:hover a.anchor { 88 | visibility: visible; 89 | } 90 | 91 | @media (max-width: 767px) { 92 | .hasAnchor:hover a.anchor { 93 | visibility: hidden; 94 | } 95 | } 96 | 97 | 98 | /* Fixes for fixed navbar --------------------------*/ 99 | 100 | .contents h1, .contents h2, .contents h3, .contents h4 { 101 | padding-top: 60px; 102 | margin-top: -40px; 103 | } 104 | 105 | /* Static header placement on mobile devices */ 106 | @media (max-width: 767px) { 107 | .navbar-fixed-top { 108 | position: absolute; 109 | } 110 | .navbar { 111 | padding: 0; 112 | } 113 | } 114 | 115 | 116 | /* Sidebar --------------------------*/ 117 | 118 | #sidebar { 119 | margin-top: 30px; 120 | } 121 | #sidebar h2 { 122 | font-size: 1.5em; 123 | margin-top: 1em; 124 | } 125 | 126 | #sidebar h2:first-child { 127 | margin-top: 0; 128 | } 129 | 130 | #sidebar .list-unstyled li { 131 | margin-bottom: 0.5em; 132 | } 133 | 134 | .orcid { 135 | height: 16px; 136 | vertical-align: middle; 137 | } 138 | 139 | /* Reference index & topics ----------------------------------------------- */ 140 | 141 | .ref-index th {font-weight: normal;} 142 | 143 | .ref-index td {vertical-align: top;} 144 | .ref-index .icon {width: 40px;} 145 | .ref-index .alias {width: 40%;} 146 | .ref-index-icons .alias {width: calc(40% - 40px);} 147 | .ref-index .title {width: 60%;} 148 | 149 | .ref-arguments th {text-align: right; padding-right: 10px;} 150 | .ref-arguments th, .ref-arguments td {vertical-align: top;} 151 | .ref-arguments .name {width: 20%;} 152 | .ref-arguments .desc {width: 80%;} 153 | 154 | /* Nice scrolling for wide elements --------------------------------------- */ 155 | 156 | table { 157 | display: block; 158 | overflow: auto; 159 | } 160 | 161 | /* Syntax highlighting ---------------------------------------------------- */ 162 | 163 | pre { 164 | word-wrap: normal; 165 | word-break: normal; 166 | border: 1px solid #eee; 167 | } 168 | 169 | pre, code { 170 | background-color: #f8f8f8; 171 | color: #333; 172 | } 173 | 174 | pre code { 175 | overflow: auto; 176 | word-wrap: normal; 177 | white-space: pre; 178 | } 179 | 180 | pre .img { 181 | margin: 5px 0; 182 | } 183 | 184 | pre .img img { 185 | background-color: #fff; 186 | display: block; 187 | height: auto; 188 | } 189 | 190 | code a, pre a { 191 | color: #375f84; 192 | } 193 | 194 | a.sourceLine:hover { 195 | text-decoration: none; 196 | } 197 | 198 | .fl {color: #1514b5;} 199 | .fu {color: #000000;} /* function */ 200 | .ch,.st {color: #036a07;} /* string */ 201 | .kw {color: #264D66;} /* keyword */ 202 | .co {color: #888888;} /* comment */ 203 | 204 | .message { color: black; font-weight: bolder;} 205 | .error { color: orange; font-weight: bolder;} 206 | .warning { color: #6A0366; font-weight: bolder;} 207 | 208 | /* Clipboard --------------------------*/ 209 | 210 | .hasCopyButton { 211 | position: relative; 212 | } 213 | 214 | .btn-copy-ex { 215 | position: absolute; 216 | right: 0; 217 | top: 0; 218 | visibility: hidden; 219 | } 220 | 221 | .hasCopyButton:hover button.btn-copy-ex { 222 | visibility: visible; 223 | } 224 | 225 | /* mark.js ----------------------------*/ 226 | 227 | mark { 228 | background-color: rgba(255, 255, 51, 0.5); 229 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 230 | padding: 1px; 231 | } 232 | 233 | /* vertical spacing after htmlwidgets */ 234 | .html-widget { 235 | margin-bottom: 10px; 236 | } 237 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $("#sidebar") 6 | .stick_in_parent({offset_top: 40}) 7 | .on('sticky_kit:bottom', function(e) { 8 | $(this).parent().css('position', 'static'); 9 | }) 10 | .on('sticky_kit:unbottom', function(e) { 11 | $(this).parent().css('position', 'relative'); 12 | }); 13 | 14 | $('body').scrollspy({ 15 | target: '#sidebar', 16 | offset: 60 17 | }); 18 | 19 | $('[data-toggle="tooltip"]').tooltip(); 20 | 21 | var cur_path = paths(location.pathname); 22 | var links = $("#navbar ul li a"); 23 | var max_length = -1; 24 | var pos = -1; 25 | for (var i = 0; i < links.length; i++) { 26 | if (links[i].getAttribute("href") === "#") 27 | continue; 28 | // Ignore external links 29 | if (links[i].host !== location.host) 30 | continue; 31 | 32 | var nav_path = paths(links[i].pathname); 33 | 34 | var length = prefix_length(nav_path, cur_path); 35 | if (length > max_length) { 36 | max_length = length; 37 | pos = i; 38 | } 39 | } 40 | 41 | // Add class to parent
  • , and enclosing
  • if in dropdown 42 | if (pos >= 0) { 43 | var menu_anchor = $(links[pos]); 44 | menu_anchor.parent().addClass("active"); 45 | menu_anchor.closest("li.dropdown").addClass("active"); 46 | } 47 | }); 48 | 49 | function paths(pathname) { 50 | var pieces = pathname.split("/"); 51 | pieces.shift(); // always starts with / 52 | 53 | var end = pieces[pieces.length - 1]; 54 | if (end === "index.html" || end === "") 55 | pieces.pop(); 56 | return(pieces); 57 | } 58 | 59 | // Returns -1 if not found 60 | function prefix_length(needle, haystack) { 61 | if (needle.length > haystack.length) 62 | return(-1); 63 | 64 | // Special case for length-0 haystack, since for loop won't run 65 | if (haystack.length === 0) { 66 | return(needle.length === 0 ? 0 : -1); 67 | } 68 | 69 | for (var i = 0; i < haystack.length; i++) { 70 | if (needle[i] != haystack[i]) 71 | return(i); 72 | } 73 | 74 | return(haystack.length); 75 | } 76 | 77 | /* Clipboard --------------------------*/ 78 | 79 | function changeTooltipMessage(element, msg) { 80 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 81 | element.setAttribute('data-original-title', msg); 82 | $(element).tooltip('show'); 83 | element.setAttribute('data-original-title', tooltipOriginalTitle); 84 | } 85 | 86 | if(ClipboardJS.isSupported()) { 87 | $(document).ready(function() { 88 | var copyButton = ""; 89 | 90 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 91 | 92 | // Insert copy buttons: 93 | $(copyButton).prependTo(".hasCopyButton"); 94 | 95 | // Initialize tooltips: 96 | $('.btn-copy-ex').tooltip({container: 'body'}); 97 | 98 | // Initialize clipboard: 99 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 100 | text: function(trigger) { 101 | return trigger.parentNode.textContent; 102 | } 103 | }); 104 | 105 | clipboardBtnCopies.on('success', function(e) { 106 | changeTooltipMessage(e.trigger, 'Copied!'); 107 | e.clearSelection(); 108 | }); 109 | 110 | clipboardBtnCopies.on('error', function() { 111 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 112 | }); 113 | }); 114 | } 115 | })(window.jQuery || window.$) 116 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: '2.6' 2 | pkgdown: 1.3.0 3 | pkgdown_sha: ~ 4 | articles: [] 5 | urls: 6 | reference: https://tbltools.mikewk.com/reference 7 | article: https://tbltools.mikewk.com/articles 8 | 9 | -------------------------------------------------------------------------------- /docs/reference/bind_cols_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Bind columns — bind_cols_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Bind together the columns of two or more data frames.

    117 | 118 |
    119 | 120 |
    bind_cols_data(...)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 |
    ...

    Data frames

    130 | 131 |

    Value

    132 | 133 |

    Single data frame with combined columns

    134 | 135 | 136 |
    137 | 146 |
    147 | 148 | 157 |
    158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/reference/decr.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Decreasing order — decr • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Arranges vector in descending order

    117 | 118 |
    119 | 120 |
    decr(x)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 |
    x

    Input vector

    130 | 131 |

    Value

    132 | 133 |

    Reordered vector

    134 | 135 | 136 |

    Examples

    137 |
    ## decreasing 1:10 138 | decr(1:10)
    #> [1] -1 -2 -3 -4 -5 -6 -7 -8 -9 -10
    139 |
    140 | 151 |
    152 | 153 | 162 |
    163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /docs/reference/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkearney/tbltools/c19a0db8b8eab5fd92ffbb1933de3374e1839cc5/docs/reference/figures/logo.png -------------------------------------------------------------------------------- /docs/reference/group_by_data_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Group row numbers in grouped data — group_by_data_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Returns row numbers for each group in grouped data

    117 | 118 |
    119 | 120 |
    group_by_data_data(x)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 |
    x

    Groupted data frame

    130 | 131 |

    Value

    132 | 133 |

    List of row numbers for each group

    134 | 135 | 136 |
    137 | 146 |
    147 | 148 | 157 |
    158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/reference/group_by_data_groups.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Groups in grouped data — group_by_data_groups • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Returns grouping variable names of grouped data

    117 | 118 |
    119 | 120 |
    group_by_data_groups(x)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 |
    x

    Grouped data frame

    130 | 131 |

    Value

    132 | 133 |

    Names of grouping variables

    134 | 135 | 136 |
    137 | 146 |
    147 | 148 | 157 |
    158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/reference/group_data_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Group row numbers in grouped data — group_data_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Returns row numbers for each group in grouped data

    117 | 118 |
    119 | 120 |
    group_data_data(x)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 |
    x

    Groupted data frame

    130 | 131 |

    Value

    132 | 133 |

    List of row numbers for each group

    134 | 135 | 136 |
    137 | 146 |
    147 | 148 | 157 |
    158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/reference/group_data_groups.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Groups in grouped data — group_data_groups • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Returns grouping variable names of grouped data

    117 | 118 |
    119 | 120 |
    group_data_groups(x)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 |
    x

    Grouped data frame

    130 | 131 |

    Value

    132 | 133 |

    Names of grouping variables

    134 | 135 | 136 |
    137 | 146 |
    147 | 148 | 157 |
    158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/reference/mutate_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Mutate data — mutate_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Wrangle data by adding or transforming columns

    117 | 118 |
    119 | 120 |
    mutate_data(.data, ...)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 134 | 135 |
    .data

    Data frame

    ...

    One or more expressions using non-standard evaluation designed 132 | to return a column of values. These should be named variables. Any names 133 | already found in the input data will override those input data frame columns

    136 | 137 |

    Value

    138 | 139 |

    Mutated data frame

    140 | 141 |

    See also

    142 | 143 |

    Other mutate: mutate_if_data

    144 | 145 | 146 |
    147 | 158 |
    159 | 160 | 169 |
    170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /docs/reference/mutate_if_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Mutate certain columns — mutate_if_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Wrangle only columns that pass a logical test

    117 | 118 |
    119 | 120 |
    mutate_if_data(.data, .predicate, .f)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 137 | 138 |
    .data

    Input data frame

    .predicate

    Function applied to each column evaluating to a logical

    .f

    Function applied to each .predicate-passing column. Can be written 136 | in the formula ~ .x format.

    139 | 140 |

    Value

    141 | 142 |

    Data frame with .predicate-passing columns mutated.

    143 | 144 |

    See also

    145 | 146 |

    Other mutate: mutate_data

    147 | 148 | 149 |
    150 | 161 |
    162 | 163 | 172 |
    173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /docs/reference/n_obs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Number of observersations — n_obs • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 53 | 54 | 55 | 56 | 57 | 58 |
    59 |
    60 | 103 | 104 | 105 |
    106 | 107 |
    108 |
    109 | 114 | 115 |
    116 | 117 |

    Returns number of observations in group (if no group then number of obs 118 | in data frame)

    119 | 120 |
    121 | 122 |
    n_obs()
    123 | 124 |

    Value

    125 | 126 |

    Number of observations in group

    127 | 128 | 129 |
    130 | 138 |
    139 | 140 | 149 |
    150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /docs/reference/pipe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Pipe operator — %>% • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    See magrittr::%>% for details.

    117 | 118 |
    119 | 120 |
    lhs %>% rhs
    121 | 122 | 123 |
    124 | 130 |
    131 | 132 | 141 |
    142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/reference/print.tbl_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Print tbl_data — print.tbl_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Method for printing pseduo tibble

    117 | 118 |
    119 | 120 |
    # S3 method for tbl_data
    121 | print(x, n = NULL, ...)
    122 | 123 |

    Arguments

    124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 134 | 135 | 136 | 137 | 138 | 139 |
    x

    Input object

    n

    Maximum number of rows to print, if NULL (default) defaults to 133 | getOption("tbltools.print_n", 10).

    ...

    Other args passed to tibble or data.frame print.

    140 | 141 | 142 |
    143 | 150 |
    151 | 152 | 161 |
    162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /docs/reference/pull_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Pull data — pull_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Pull (extract) data from a data frame

    117 | 118 |
    119 | 120 |
    pull_data(.data, ...)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 |
    .data

    Input data frame

    ...

    Unquoted name of column to pull from data frame

    134 | 135 |

    Value

    136 | 137 |

    A column pulled from its data frame (inheriting whatever class the 138 | column is)

    139 | 140 | 141 |

    Examples

    142 |
    143 | ## pull the 'y' variable from the data frame 144 | tbl_data(x = rnorm(5), y = letters[1:5]) %>% pull_data(y)
    #> [1] "a" "b" "c" "d" "e"
    145 |
    146 |
    147 | 158 |
    159 | 160 | 169 |
    170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /docs/reference/select_cols.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Select columns — select_cols • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Select columns with non-standard evaluation

    117 | 118 |
    119 | 120 |
    select_cols(.data, ...)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 |
    .data

    Input data frame

    ...

    Unquoted names of columns to select

    134 | 135 |

    Value

    136 | 137 |

    Data frame with select columns

    138 | 139 | 140 |
    141 | 150 |
    151 | 152 | 161 |
    162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /docs/reference/select_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Select columns — select_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Select columns with non-standard evaluation

    117 | 118 |
    119 | 120 |
    select_data(.data, ...)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 |
    .data

    Input data frame

    ...

    Unquoted names of columns to select

    134 | 135 |

    Value

    136 | 137 |

    Data frame with select columns

    138 | 139 | 140 |
    141 | 150 |
    151 | 152 | 161 |
    162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /docs/reference/summarise_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Summarise data — summarise_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Returns a summary-level data frame

    117 | 118 |
    119 | 120 |
    summarise_data(.data, ...)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 133 | 134 |
    .data

    Data frame

    ...

    One or more namecd expressions evaluating with non-standard evaluation 132 | to a single summary value.

    135 | 136 |

    Value

    137 | 138 |

    A summary-level data frame

    139 | 140 | 141 |
    142 | 151 |
    152 | 153 | 162 |
    163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /docs/reference/tbl_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | tbl data — tbl_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Create a tibble data frame

    117 | 118 |
    119 | 120 |
    tbl_data(...)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 129 | 130 |
    ...

    A data frame, vector, or list of values of equal or single-value 128 | length–similar to data.frame.

    131 | 132 |

    Value

    133 | 134 |

    An object of class c("tbl_data", "tbl_df", "tbl", "data.frame")

    135 | 136 | 137 |
    138 | 147 |
    148 | 149 | 158 |
    159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /docs/reference/tbltools-package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | tbltools: Tools for Working with Tibbles — tbltools-package • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 |
    61 |
    62 | 105 | 106 | 107 |
    108 | 109 |
    110 |
    111 | 116 | 117 |
    118 | 119 |

    120 |

    Tools for working with tibbles, or data.frame-like objects 121 | generated by the 'tibble' package <https://tibble.tidyverse.org/>. Functions 122 | assist in converting objects to tibbles and creating frequency tables.

    123 | 124 |
    125 | 126 | 127 |

    See also

    128 | 129 | 133 | 134 | 135 |
    136 | 146 |
    147 | 148 | 157 |
    158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/reference/ungroup_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Ungroup data — ungroup_data • tbltools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 |
    58 |
    59 | 102 | 103 | 104 |
    105 | 106 |
    107 |
    108 | 113 | 114 |
    115 | 116 |

    Ungroups grouped data

    117 | 118 |
    119 | 120 |
    ungroup_data(.data)
    121 | 122 |

    Arguments

    123 | 124 | 125 | 126 | 127 | 128 | 129 |
    .data

    Grouped data

    130 | 131 |

    Value

    132 | 133 |

    Data grame without groups attribute

    134 | 135 | 136 |
    137 | 146 |
    147 | 148 | 157 |
    158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://tbltools.mikewk.com/index.html 5 | 6 | 7 | https://tbltools.mikewk.com/reference/arrange_data.html 8 | 9 | 10 | https://tbltools.mikewk.com/reference/as_tbl_data.html 11 | 12 | 13 | https://tbltools.mikewk.com/reference/bind_cols_data.html 14 | 15 | 16 | https://tbltools.mikewk.com/reference/bind_rows_data.html 17 | 18 | 19 | https://tbltools.mikewk.com/reference/decr.html 20 | 21 | 22 | https://tbltools.mikewk.com/reference/env_tbls.html 23 | 24 | 25 | https://tbltools.mikewk.com/reference/filter_data.html 26 | 27 | 28 | https://tbltools.mikewk.com/reference/group_by_data.html 29 | 30 | 31 | https://tbltools.mikewk.com/reference/group_by_data_data.html 32 | 33 | 34 | https://tbltools.mikewk.com/reference/group_by_data_groups.html 35 | 36 | 37 | https://tbltools.mikewk.com/reference/join.html 38 | 39 | 40 | https://tbltools.mikewk.com/reference/mutate_data.html 41 | 42 | 43 | https://tbltools.mikewk.com/reference/mutate_if_data.html 44 | 45 | 46 | https://tbltools.mikewk.com/reference/n_obs.html 47 | 48 | 49 | https://tbltools.mikewk.com/reference/pipe.html 50 | 51 | 52 | https://tbltools.mikewk.com/reference/print.tbl_data.html 53 | 54 | 55 | https://tbltools.mikewk.com/reference/pull_data.html 56 | 57 | 58 | https://tbltools.mikewk.com/reference/repos_back.html 59 | 60 | 61 | https://tbltools.mikewk.com/reference/repos_front.html 62 | 63 | 64 | https://tbltools.mikewk.com/reference/select_data.html 65 | 66 | 67 | https://tbltools.mikewk.com/reference/slice_data.html 68 | 69 | 70 | https://tbltools.mikewk.com/reference/summarise_data.html 71 | 72 | 73 | https://tbltools.mikewk.com/reference/tabsort.html 74 | 75 | 76 | https://tbltools.mikewk.com/reference/tbl_data.html 77 | 78 | 79 | https://tbltools.mikewk.com/reference/tbl_data_frame.html 80 | 81 | 82 | https://tbltools.mikewk.com/reference/tbltools-package.html 83 | 84 | 85 | https://tbltools.mikewk.com/reference/ungroup_data.html 86 | 87 | 88 | -------------------------------------------------------------------------------- /man/arrange_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/arrange.R 3 | \name{arrange_data} 4 | \alias{arrange_data} 5 | \title{Arrange rows} 6 | \usage{ 7 | arrange_data(.data, ...) 8 | } 9 | \arguments{ 10 | \item{.data}{data frame} 11 | 12 | \item{...}{One or more unquoted names of columns on which to arrange the rows. If none 13 | are supplied, the data are returned as is. By default, ordering is done in ascending 14 | order. To orer in descending order, use \code{\link{decr}} on desired variable(s).} 15 | } 16 | \value{ 17 | Rearranged data frame 18 | } 19 | \description{ 20 | Arrange rows via descending or ascending column values 21 | } 22 | \examples{ 23 | 24 | ## data frame to arrange 25 | dat <- data.frame( 26 | a = c(rep("a", 3), rep("b", 3), rep("c", 4)), 27 | b = c( 3, 3, 2, 8, 8, 1, 5, 5, 5, 9), 28 | c = c(-1, 0, 0, -5, 0, 2, -2, -4, 1, 0), 29 | stringsAsFactors = FALSE 30 | ) 31 | 32 | ## arrange by one column 33 | arrange_data(dat, a) 34 | 35 | ## arrange by multiple columns 36 | arrange_data(dat, decr(a), b, c) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /man/as_tbl_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tbl.R 3 | \name{as_tbl_data} 4 | \alias{as_tbl_data} 5 | \title{as_tbl_data} 6 | \usage{ 7 | as_tbl_data(x, row_names = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{Data frame or data frame-like input.} 11 | 12 | \item{row_names}{Logical indicating whether to convert non-null row names 13 | into the first column.} 14 | } 15 | \description{ 16 | Converts data objects to tibbles. 17 | } 18 | \examples{ 19 | ## data with row names 20 | d <- data.frame(x = rnorm(5), y = rnorm(5), row.names = letters[1:5]) 21 | 22 | ## convert to tibble 23 | as_tbl_data(d) 24 | 25 | ## convert to tibble and create row_names variable 26 | as_tbl_data(d, row_names = TRUE) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /man/bind_cols_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bind_cols.R 3 | \name{bind_cols_data} 4 | \alias{bind_cols_data} 5 | \title{Bind columns} 6 | \usage{ 7 | bind_cols_data(...) 8 | } 9 | \arguments{ 10 | \item{...}{Data frames} 11 | } 12 | \value{ 13 | Single data frame with combined columns 14 | } 15 | \description{ 16 | Bind together the columns of two or more data frames. 17 | } 18 | -------------------------------------------------------------------------------- /man/bind_rows_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bind_rows.R 3 | \name{bind_rows_data} 4 | \alias{bind_rows_data} 5 | \title{Bind rows} 6 | \usage{ 7 | bind_rows_data(..., fill = FALSE) 8 | } 9 | \arguments{ 10 | \item{...}{Input data frames or list of data frames} 11 | 12 | \item{fill}{Logical indicating whether to fill missing columns in data frames 13 | with missing values.} 14 | } 15 | \value{ 16 | The list collapsed into a single data frame 17 | } 18 | \description{ 19 | Convenient wrapper around \code{\link[base]{do.call}("rbind", ...)} that 20 | (a) sets the 'quote' argument to TRUE and (b) fills data frames with missing 21 | columns with NAs of the appropriate class. 22 | } 23 | \examples{ 24 | 25 | ## list of data frames with inconsistent columns 26 | x <- as_tbl_data(mtcars[1:3, ]) 27 | xx <- x 28 | xx$y <- "a" 29 | l <- list(x, xx, mtcars) 30 | 31 | ## bind rows and fill missing columns with NAs 32 | bind_rows_data(l, fill = TRUE) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /man/decr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/decr.R 3 | \name{decr} 4 | \alias{decr} 5 | \title{Decreasing order} 6 | \usage{ 7 | decr(x) 8 | } 9 | \arguments{ 10 | \item{x}{Input vector} 11 | } 12 | \value{ 13 | Reordered vector 14 | } 15 | \description{ 16 | Arranges vector in descending order 17 | } 18 | \examples{ 19 | ## decreasing 1:10 20 | decr(1:10) 21 | } 22 | -------------------------------------------------------------------------------- /man/env_tbls.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tbl.R 3 | \name{env_tbls} 4 | \alias{env_tbls} 5 | \title{Convert all data frames in environment into tibbles} 6 | \usage{ 7 | env_tbls(env = globalenv(), row_names = TRUE) 8 | } 9 | \arguments{ 10 | \item{env}{Name of environment from which data frames should be converted to tibbles. 11 | Defaults to global environment.} 12 | 13 | \item{row_names}{Logical indicating whether to create a row_names variable if non-auto 14 | row names are found.} 15 | } 16 | \value{ 17 | The function will print messages when converting occurs and it will print a final 18 | completion message, but otherwise returns nothing. 19 | } 20 | \description{ 21 | Converts data frames found in a given environment into tibbles (tbl_df) 22 | } 23 | \examples{ 24 | ## data with row names 25 | d <- data.frame(x = rnorm(5), y = rnorm(5), row.names = letters[1:5]) 26 | 27 | ## convert data frames in global environment to tibbles 28 | env_tbls() 29 | 30 | } 31 | -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkearney/tbltools/c19a0db8b8eab5fd92ffbb1933de3374e1839cc5/man/figures/logo.png -------------------------------------------------------------------------------- /man/filter_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/filter.R 3 | \name{filter_data} 4 | \alias{filter_data} 5 | \title{Filter rows} 6 | \usage{ 7 | filter_data(.data, ...) 8 | } 9 | \arguments{ 10 | \item{.data}{Data frame or two dimensional array} 11 | 12 | \item{...}{Each argument/expression should should evaluate and reduce down to 13 | an integer (row number) or logical vector. The filter will keep all row 14 | numbers that appear in all evaluated expressions (commas are the equivalent 15 | to \code{&}. Row numbers higher than what exists in x will be ignored. Any 16 | numeric vector must be either all positive or all negative (excludes). This 17 | function uses non-standard evaluation–users can refer to column names 18 | without quotations.} 19 | } 20 | \value{ 21 | Sliced/filtered data frame 22 | } 23 | \description{ 24 | Filter rows via integer/numeric position or logical vector 25 | } 26 | \examples{ 27 | set.seed(12) 28 | d <- data.frame( 29 | mpg = rnorm(100, 25, 3), 30 | gear = sample(3:6, 100, replace = TRUE), 31 | vs = sample(0:1, 100, replace = TRUE), 32 | stringsAsFactors = FALSE 33 | ) 34 | 35 | filter_data(d, mpg > 30) 36 | filter_data(d, !mpg < 30) 37 | filter_data(d, mpg > 30, !mpg < 30) 38 | filter_data(d, mpg > 30, gear == 4) 39 | filter_data(d, mpg > 30 | gear == 4, vs == 1) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /man/group_by_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/group.R 3 | \name{group_by_data} 4 | \alias{group_by_data} 5 | \title{Group data} 6 | \usage{ 7 | group_by_data(.data, ...) 8 | } 9 | \arguments{ 10 | \item{.data}{Data frame} 11 | 12 | \item{...}{Unquoted (non-standard evaluation) name(s) of group variable(s).} 13 | } 14 | \value{ 15 | A data frame with groups attribute 16 | } 17 | \description{ 18 | Indicate grouping variables in data frame 19 | } 20 | \examples{ 21 | d <- data.frame(a = c("a", "b", "c"), b = 1:3, stringsAsFactors = FALSE) 22 | group_by_data(d, a) 23 | } 24 | -------------------------------------------------------------------------------- /man/group_by_data_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/group.R 3 | \name{group_by_data_data} 4 | \alias{group_by_data_data} 5 | \title{Group row numbers in grouped data} 6 | \usage{ 7 | group_by_data_data(x) 8 | } 9 | \arguments{ 10 | \item{x}{Groupted data frame} 11 | } 12 | \value{ 13 | List of row numbers for each group 14 | } 15 | \description{ 16 | Returns row numbers for each group in grouped data 17 | } 18 | -------------------------------------------------------------------------------- /man/group_by_data_groups.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/group.R 3 | \name{group_by_data_groups} 4 | \alias{group_by_data_groups} 5 | \title{Groups in grouped data} 6 | \usage{ 7 | group_by_data_groups(x) 8 | } 9 | \arguments{ 10 | \item{x}{Grouped data frame} 11 | } 12 | \value{ 13 | Names of grouping variables 14 | } 15 | \description{ 16 | Returns grouping variable names of grouped data 17 | } 18 | -------------------------------------------------------------------------------- /man/join.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/join.R 3 | \name{full_join_data} 4 | \alias{full_join_data} 5 | \alias{left_join_data} 6 | \alias{right_join_data} 7 | \title{Joins} 8 | \usage{ 9 | full_join_data(x, y, by = NULL) 10 | 11 | left_join_data(x, y, by = NULL) 12 | 13 | right_join_data(x, y, by = NULL) 14 | } 15 | \arguments{ 16 | \item{x}{Left or first data frame} 17 | 18 | \item{y}{Right or second data frame} 19 | 20 | \item{by}{Name (character) of variable(s) on which to join} 21 | } 22 | \value{ 23 | Joined (merged) data frame 24 | } 25 | \description{ 26 | Full join: join two data frames preserving all possible information 27 | 28 | Left join: Join two data frames by matching the second (right) data frame to 29 | the left (first) such that the structure of the first (left) data frame is 30 | preserved 31 | 32 | Right join: Join two data frames by matching the first (left) data frame to 33 | the right (second) such that the structure of the second (right) data frame 34 | is preserved 35 | } 36 | \examples{ 37 | 38 | d1 <- tbl_data( 39 | x = 1:10, 40 | y = rnorm(10), 41 | z = letters[1:10] 42 | ) 43 | d2 <- tbl_data( 44 | x = sample(1:10, 20, replace = TRUE), 45 | y2 = rnorm(20) 46 | ) 47 | 48 | ## left join 49 | left_join_data(d1, d2) 50 | 51 | ## right join 52 | right_join_data(d1, d2) 53 | 54 | ## full join 55 | full_join_data(d1, d2) 56 | 57 | } 58 | -------------------------------------------------------------------------------- /man/mutate_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mutate.R 3 | \name{mutate_data} 4 | \alias{mutate_data} 5 | \title{Mutate data} 6 | \usage{ 7 | mutate_data(.data, ...) 8 | } 9 | \arguments{ 10 | \item{.data}{Data frame} 11 | 12 | \item{...}{One or more expressions using non-standard evaluation designed 13 | to return a column of values. These should be named variables. Any names 14 | already found in the input data will override those input data frame columns} 15 | } 16 | \value{ 17 | Mutated data frame 18 | } 19 | \description{ 20 | Wrangle data by adding or transforming columns 21 | } 22 | \seealso{ 23 | Other mutate: \code{\link{mutate_if_data}} 24 | } 25 | \concept{mutate} 26 | -------------------------------------------------------------------------------- /man/mutate_if_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mutate.R 3 | \name{mutate_if_data} 4 | \alias{mutate_if_data} 5 | \title{Mutate certain columns} 6 | \usage{ 7 | mutate_if_data(.data, .predicate, .f) 8 | } 9 | \arguments{ 10 | \item{.data}{Input data frame} 11 | 12 | \item{.predicate}{Function applied to each column evaluating to a logical} 13 | 14 | \item{.f}{Function applied to each .predicate-passing column. Can be written 15 | in the formula \code{~ .x} format.} 16 | } 17 | \value{ 18 | Data frame with .predicate-passing columns mutated. 19 | } 20 | \description{ 21 | Wrangle only columns that pass a logical test 22 | } 23 | \seealso{ 24 | Other mutate: \code{\link{mutate_data}} 25 | } 26 | \concept{mutate} 27 | -------------------------------------------------------------------------------- /man/n_obs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/n_obs.R 3 | \name{n_obs} 4 | \alias{n_obs} 5 | \title{Number of observersations} 6 | \usage{ 7 | n_obs() 8 | } 9 | \value{ 10 | Number of observations in group 11 | } 12 | \description{ 13 | Returns number of observations in group (if no group then number of obs 14 | in data frame) 15 | } 16 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{magrittr::\link[magrittr]{\%>\%}} for details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/print.tbl_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/print.R 3 | \name{print.tbl_data} 4 | \alias{print.tbl_data} 5 | \title{Print tbl_data} 6 | \usage{ 7 | \method{print}{tbl_data}(x, n = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Input object} 11 | 12 | \item{n}{Maximum number of rows to print, if NULL (default) defaults to 13 | \code{getOption("tbltools.print_n", 10)}.} 14 | 15 | \item{...}{Other args passed to tibble or data.frame print.} 16 | } 17 | \description{ 18 | Method for printing pseduo tibble 19 | } 20 | -------------------------------------------------------------------------------- /man/pull_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pull.R 3 | \name{pull_data} 4 | \alias{pull_data} 5 | \title{Pull data} 6 | \usage{ 7 | pull_data(.data, ...) 8 | } 9 | \arguments{ 10 | \item{.data}{Input data frame} 11 | 12 | \item{...}{Unquoted name of column to pull from data frame} 13 | } 14 | \value{ 15 | A column pulled from its data frame (inheriting whatever class the 16 | column is) 17 | } 18 | \description{ 19 | Pull (extract) data from a data frame 20 | } 21 | \examples{ 22 | 23 | ## pull the 'y' variable from the data frame 24 | tbl_data(x = rnorm(5), y = letters[1:5]) \%>\% pull_data(y) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /man/repos_back.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/repos.R 3 | \name{repos_back} 4 | \alias{repos_back} 5 | \title{move vars to back} 6 | \usage{ 7 | repos_back(data, ...) 8 | } 9 | \arguments{ 10 | \item{data}{data frame} 11 | 12 | \item{...}{columns to move to back} 13 | } 14 | \value{ 15 | Reordered data frame. 16 | } 17 | \description{ 18 | move vars to back 19 | } 20 | \examples{ 21 | ## data with row names 22 | d <- data.frame(x = rnorm(5), y = rnorm(5), row.names = letters[1:5]) 23 | 24 | ## move x to back 25 | repos_back(d, x) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/repos_front.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/repos.R 3 | \name{repos_front} 4 | \alias{repos_front} 5 | \title{move vars to front} 6 | \usage{ 7 | repos_front(data, ...) 8 | } 9 | \arguments{ 10 | \item{data}{data frame} 11 | 12 | \item{...}{columns to move to front} 13 | } 14 | \value{ 15 | Reordered data frame. 16 | } 17 | \description{ 18 | move vars to front 19 | } 20 | \examples{ 21 | ## data with row names 22 | d <- data.frame(x = rnorm(5), y = rnorm(5), row.names = letters[1:5]) 23 | 24 | ## move y to front 25 | repos_front(d, y) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/select_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/select.R 3 | \name{select_data} 4 | \alias{select_data} 5 | \title{Select columns} 6 | \usage{ 7 | select_data(.data, ...) 8 | } 9 | \arguments{ 10 | \item{.data}{Input data frame} 11 | 12 | \item{...}{Unquoted names of columns to select} 13 | } 14 | \value{ 15 | Data frame with select columns 16 | } 17 | \description{ 18 | Select columns with non-standard evaluation 19 | } 20 | -------------------------------------------------------------------------------- /man/slice_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/slice.R 3 | \name{slice_data} 4 | \alias{slice_data} 5 | \title{Slice data} 6 | \usage{ 7 | slice_data(.data, ...) 8 | } 9 | \arguments{ 10 | \item{.data}{Input data frame} 11 | 12 | \item{...}{Expression to evaluate to integer row positions} 13 | } 14 | \value{ 15 | .data of evaluated row positions 16 | } 17 | \description{ 18 | Slice data by row number 19 | } 20 | \examples{ 21 | 22 | ## data set 23 | d <- tbl_data(x = rnorm(10), y = rnorm(10)) 24 | 25 | ## slice first 4 rows 26 | slice_data(d, 1:4) 27 | } 28 | -------------------------------------------------------------------------------- /man/summarise_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summarise.R 3 | \name{summarise_data} 4 | \alias{summarise_data} 5 | \title{Summarise data} 6 | \usage{ 7 | summarise_data(.data, ...) 8 | } 9 | \arguments{ 10 | \item{.data}{Data frame} 11 | 12 | \item{...}{One or more namecd expressions evaluating with non-standard evaluation 13 | to a single summary value.} 14 | } 15 | \value{ 16 | A summary-level data frame 17 | } 18 | \description{ 19 | Returns a summary-level data frame 20 | } 21 | -------------------------------------------------------------------------------- /man/tabsort.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tabsort.R 3 | \name{tabsort} 4 | \alias{tabsort} 5 | \alias{ntbl} 6 | \title{tabsort} 7 | \usage{ 8 | tabsort(.data, ..., prop = TRUE, na_omit = TRUE, sort = TRUE) 9 | 10 | ntbl(.data, ...) 11 | } 12 | \arguments{ 13 | \item{.data}{Data} 14 | 15 | \item{...}{Unquoted column names of variables to include in table. Default 16 | is to use all columns.} 17 | 18 | \item{prop}{Logical indicating whether to include a proportion of total 19 | obs column.} 20 | 21 | \item{na_omit}{Logical indicating whether to exclude missing. If all 22 | responses are missing, a missing value is used as the single category.} 23 | 24 | \item{sort}{Logical indicating whether to sort the returned object.} 25 | } 26 | \value{ 27 | Frequency tbl 28 | } 29 | \description{ 30 | Returns a sorted (descending) frequency tbl 31 | } 32 | \examples{ 33 | 34 | ## generate example data 35 | x <- sample(letters[1:4], 200, replace = TRUE) 36 | y <- sample(letters[5:8], 200, replace = TRUE) 37 | 38 | ## count and sort frequencies for each vector 39 | tabsort(x) 40 | tabsort(y) 41 | 42 | ## combine x and y into data frame 43 | dat <- data.frame(x, y) 44 | 45 | ## select columns and create freq table 46 | tabsort(dat, x) 47 | tabsort(dat, x, y) 48 | 49 | } 50 | -------------------------------------------------------------------------------- /man/tbl_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tbl.R 3 | \name{tbl_data} 4 | \alias{tbl_data} 5 | \title{tbl data} 6 | \usage{ 7 | tbl_data(...) 8 | } 9 | \arguments{ 10 | \item{...}{A data frame, vector, or list of values of equal or single-value 11 | length–similar to \link[base]{data.frame}.} 12 | } 13 | \value{ 14 | An object of class \code{c("tbl_data", "tbl_df", "tbl", "data.frame")} 15 | } 16 | \description{ 17 | Create a tibble data frame 18 | } 19 | -------------------------------------------------------------------------------- /man/tbl_data_frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tbl_frame.R 3 | \name{tbl_data_frame} 4 | \alias{tbl_data_frame} 5 | \title{Create tbl_data_frame} 6 | \usage{ 7 | tbl_data_frame(...) 8 | } 9 | \arguments{ 10 | \item{...}{Column vectors or expressions that reduce down to desired column vectors of 11 | data frame} 12 | } 13 | \value{ 14 | A tbl_data data frame 15 | } 16 | \description{ 17 | Creates a data frame using non-standard evaluation 18 | } 19 | \examples{ 20 | 21 | ## create data frame with two random variables 22 | tbl_data_frame( 23 | a = rnorm(10), 24 | b = rnorm(10) 25 | ) 26 | 27 | ## create variables calculated using previous variables 28 | tbl_data_frame( 29 | a = rnorm(10), 30 | b = rnorm(10), 31 | c = (a + b) / 2, 32 | d = a + b + c 33 | ) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /man/tbltools-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tbltools-package.R 3 | \docType{package} 4 | \name{tbltools-package} 5 | \alias{tbltools} 6 | \alias{tbltools-package} 7 | \title{tbltools: Tools for Working with Tibbles} 8 | \description{ 9 | \if{html}{\figure{logo.png}{options: align='right'}} 10 | 11 | Tools for working with tibbles, or data.frame-like objects 12 | generated by the 'tibble' package . Functions 13 | assist in converting objects to tibbles and creating frequency tables. 14 | } 15 | \seealso{ 16 | Useful links: 17 | \itemize{ 18 | \item \url{https://github.com/mkearney/tbltools} 19 | \item Report bugs at \url{https://github.com/mkearney/tbltools/issues} 20 | } 21 | 22 | } 23 | \author{ 24 | \strong{Maintainer}: Michael W. Kearney \email{kearneymw@missouri.edu} (0000-0002-0730-4694) 25 | 26 | } 27 | \keyword{internal} 28 | -------------------------------------------------------------------------------- /man/ungroup_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/group.R 3 | \name{ungroup_data} 4 | \alias{ungroup_data} 5 | \title{Ungroup data} 6 | \usage{ 7 | ungroup_data(.data) 8 | } 9 | \arguments{ 10 | \item{.data}{Grouped data} 11 | } 12 | \value{ 13 | Data grame without groups attribute 14 | } 15 | \description{ 16 | Ungroups grouped data 17 | } 18 | -------------------------------------------------------------------------------- /pkgdown/extra.css: -------------------------------------------------------------------------------- 1 | 2 | @import url("https://fonts.googleapis.com/css?family=Roboto:400,400i,700,700i,900"); 3 | 4 | @import url(https://cdn.rawgit.com/tonsky/FiraCode/1.205/distr/fira_code.css); 5 | 6 | body { 7 | font-family: Roboto, sans-serif; 8 | font-size: 16px; 9 | line-height: 1.5; 10 | font-weight: 400; 11 | margin: .5em auto 5em auto; 12 | } 13 | 14 | h1, h2, h3, h4, .h1, .h2, .h3, .h4 { 15 | font-family: Roboto, sans-serif; 16 | font-weight: 900; 17 | } 18 | 19 | h1 {font-size: 2.1em} 20 | h2 {font-size: 1.8em} 21 | h3 {font-size: 1.6em} 22 | h4 {font-size: 1.3em} 23 | 24 | code { 25 | font-family: "Fira Code", Consolas, Monaco, Menlo, Inconsolata, monospace; 26 | } 27 | 28 | pre { 29 | box-shadow: 30 | rgba(0, 0, 0, 0.1) 0 2px 3px 1px, 31 | rgba(0, 0, 0, 0.1) 0 1px 3px 1px, 32 | rgba(0, 0, 0, 0.2) 0 1px 1px -1px; 33 | font-size: .80em; 34 | margin-left: auto; 35 | width: 98%; 36 | margin-right: auto; 37 | line-height: 1.4em; 38 | font-family: "Fira Code", Consolas, Monaco, Menlo, Inconsolata, monospace; 39 | } 40 | 41 | div.sourceCode { 42 | overflow: visible; 43 | } 44 | 45 | pre.sourceCode { 46 | margin-left: auto; 47 | margin-right: auto; 48 | } 49 | 50 | p { 51 | margin: 1.5em 0; 52 | } 53 | 54 | strong { 55 | font-family: Roboto, sans-serif; 56 | font-weight: 900; 57 | } 58 | 59 | strong code { 60 | font-family: "Fira Code", Consolas, Monaco, Menlo, Inconsolata, monospace; 61 | font-weight: 700; 62 | } 63 | 64 | code span.co, .co { 65 | color: #828f96; 66 | } 67 | 68 | code span.ot, .ot { 69 | color: #ddaa00; 70 | } 71 | 72 | .navbar-default { 73 | box-shadow: 74 | rgba(0, 0, 0, 0.1) 0 2px 3px 1px, 75 | rgba(0, 0, 0, 0.1) 0 1px 3px 1px, 76 | rgba(0, 0, 0, 0.2) 0 1px 1px -1px; 77 | background-color: #f3f3f3; 78 | border-color: #eee; 79 | } 80 | -------------------------------------------------------------------------------- /tbltools.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: XeLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(tbltools) 3 | 4 | test_check("tbltools") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-bind.R: -------------------------------------------------------------------------------- 1 | context("test-bind") 2 | 3 | 4 | test_that("bind_rows works", { 5 | d1 <- as_tbl_data(mtcars, row_names = TRUE) 6 | d2 <- d1 7 | ## each entered 8 | expect_true(is.data.frame(bind_rows_data(d1, d2, fill = TRUE))) 9 | expect_equal(nrow(bind_rows_data(d1, d2, fill = TRUE)), 64) 10 | ## as list 11 | expect_true(is.data.frame(bind_rows_data(list(d1, d2), fill = TRUE))) 12 | expect_equal(nrow(bind_rows_data(list(d1, d2), fill = TRUE)), 64) 13 | }) 14 | 15 | test_that("bind_cols works", { 16 | d1 <- as_tbl_data(mtcars, row_names = TRUE) 17 | d2 <- d1 18 | names(d2) <- paste0("bignames_", names(d2)) 19 | ## each entered 20 | expect_true(is.data.frame(bind_cols_data(d1, d2))) 21 | expect_equal(ncol(bind_rows_data(d1, d2, fill = TRUE)), 24) 22 | ## as list 23 | expect_true(is.data.frame(bind_cols_data(list(d1, d2)))) 24 | expect_equal(ncol(bind_rows_data(list(d1, d2), fill = TRUE)), 24) 25 | }) 26 | 27 | 28 | 29 | test_that("bind_rows_data", { 30 | ## list of data frames with inconsistent columns 31 | x <- tbl_data( 32 | a = letters, 33 | b = 1:26, 34 | c = rnorm(26) 35 | ) 36 | xx <- x 37 | xx$d <- "d" 38 | xxx <- x 39 | xxx$a <- factor(xxx$a) 40 | l <- list(x, xx, xxx) 41 | d <- bind_rows_data(l, fill = TRUE) 42 | expect_true(is.data.frame(d)) 43 | expect_equal(nrow(d), 78) 44 | expect_equal(ncol(d), 4) 45 | expect_true(is.character(d$a)) 46 | expect_true(is.character(d$d)) 47 | }) 48 | 49 | -------------------------------------------------------------------------------- /tests/testthat/test-group.R: -------------------------------------------------------------------------------- 1 | context("test-group") 2 | 3 | test_that("group_by_data", { 4 | d <- tbltools::tbl_data( 5 | mpg = c(10.5, 18.5, 22.5, 25.5), 6 | cyl = c( 8L, 6L, 4L, 4L), 7 | gear = c( 5L, 4L, 4L, 3L) 8 | ) 9 | o <- d %>% 10 | filter_data(mpg > 11) %>% 11 | group_by_data(cyl) %>% 12 | mutate_data(n = length(gear)) %>% 13 | summarise_data( 14 | n = unique(n), 15 | mpg = mean(mpg) 16 | ) %>% 17 | arrange_data(decr(mpg)) %>% 18 | select_data(cyl, mpg, n) 19 | expect_true(is.data.frame(o)) 20 | expect_equal(nrow(o), 2) 21 | expect_equal(ncol(o), 3) 22 | expect_equal(o$mpg, c(24, 18.5)) 23 | }) 24 | -------------------------------------------------------------------------------- /tests/testthat/test-joins.R: -------------------------------------------------------------------------------- 1 | context("test-joins") 2 | 3 | test_that("full_join, left_join, right_join", { 4 | ## mtcars data and additional cyl/new data 5 | x <- tbltools::as_tbl_data(mtcars) 6 | y <- data.frame(cyl = c(1, 4), new = c(1.25, 2.5)) 7 | 8 | expect_message(o <- full_join_data(x, y)) 9 | expect_true(is.data.frame(o)) 10 | expect_equal(nrow(o), 33) 11 | expect_equal(ncol(o), 12) 12 | expect_true("new" %in% names(o)) 13 | expect_equal(sum(is.na(o$new)), 21) 14 | 15 | expect_message(o <- left_join_data(x, y)) 16 | expect_true(is.data.frame(o)) 17 | expect_equal(nrow(o), 32) 18 | expect_equal(ncol(o), 12) 19 | expect_true("new" %in% names(o)) 20 | expect_equal(sum(is.na(o$new)), 21) 21 | 22 | expect_message(o <- right_join_data(x, y)) 23 | expect_true(is.data.frame(o)) 24 | expect_equal(nrow(o), 12) 25 | expect_equal(ncol(o), 12) 26 | expect_true("new" %in% names(o)) 27 | expect_equal(sum(is.na(o$new)), 0) 28 | }) 29 | -------------------------------------------------------------------------------- /tests/testthat/test-mutate.R: -------------------------------------------------------------------------------- 1 | context("test-mutate") 2 | 3 | test_that("mutate_if_data works", { 4 | x <- as_tbl_data(mtcars, row_names = TRUE) %>% 5 | group_by_data(cyl) %>% 6 | mutate_if_data(~ is.numeric(.x), ~ .x / mean(.x)) 7 | expect_equal(nrow(x), 32) 8 | expect_equal(ncol(x), 12) 9 | x <- as_tbl_data(mtcars, row_names = TRUE) %>% 10 | group_by_data(cyl) %>% 11 | mutate_if_data(is.numeric, ~ mean(.x)) 12 | expect_equal(length(unique(x$wt)), 3) 13 | x <- as_tbl_data(mtcars, row_names = TRUE) %>% 14 | mutate_if_data(~ is.numeric(.x), ~ .x / mean(.x)) %>% 15 | mutate_if_data(is.numeric, min) 16 | expect_equal(nrow(x), 32) 17 | expect_equal(ncol(x), 12) 18 | x <- as_tbl_data(mtcars, row_names = TRUE) %>% 19 | mutate_if_data(~ is.numeric(.x), min) 20 | expect_equal(nrow(x), 32) 21 | expect_equal(ncol(x), 12) 22 | expect_equal(n_uq(x$wt), 1) 23 | }) 24 | -------------------------------------------------------------------------------- /tests/testthat/test-print.R: -------------------------------------------------------------------------------- 1 | context("test-print") 2 | 3 | test_that("print tbl_data", { 4 | unloadNamespace("tibble") 5 | d1 <- as_tbl_data(mtcars, row_names = TRUE) 6 | d2 <- d1 7 | names(d2) <- paste0("bignames_", names(d2)) 8 | d2 <- repos_back(d2, bignames_row_names) 9 | expect_true(is.data.frame(d2)) 10 | expect_equal("bignames_row_names", names(d2)[ncol(d2)]) 11 | d1 <- repos_front(d1, mpg) 12 | expect_true(is.data.frame(d1)) 13 | expect_equal(names(d1)[1], "mpg") 14 | ow <- getOption("width") 15 | options(width = 120) 16 | d <- bind_cols_data(d2, d1) 17 | o <- capture.output(print(d)) 18 | expect_equal(length(o), 13) 19 | var_names <- strsplit(o[2], "\\s+")[[1]][-1] 20 | expect_equal(length(var_names), 8) 21 | expect_equal( 22 | c("bignames_mpg", "bignames_cyl", "bignames_disp", "bignames_hp"), 23 | var_names[1:4] 24 | ) 25 | expect_equal(nrow(slice_data(d, 1:5)), 5) 26 | expect_error(slice_data(d, 1:5, 3)) 27 | options(width = ow) 28 | }) 29 | -------------------------------------------------------------------------------- /tests/testthat/test-select.R: -------------------------------------------------------------------------------- 1 | context("test-select") 2 | 3 | test_that("select_data", { 4 | ## list of data frames with inconsistent columns 5 | x <- data.frame( 6 | a = letters, 7 | b = 1:26, 8 | c = rnorm(26), 9 | d = 0, 10 | e = TRUE, 11 | f = sample(c(TRUE, FALSE), 26, replace = TRUE), 12 | g = sample(LETTERS), 13 | stringsAsFactors = FALSE 14 | ) 15 | d <- select_data(x, a, b) 16 | expect_true(is.data.frame(d)) 17 | expect_equal(nrow(d), 26) 18 | expect_equal(ncol(d), 2) 19 | expect_true(is.character(d$a)) 20 | expect_true(is.integer(d$b)) 21 | 22 | d <- select_data(x, -c) 23 | expect_true(is.data.frame(d)) 24 | expect_equal(nrow(d), 26) 25 | expect_equal(ncol(d), 6) 26 | expect_true(is.character(d$a)) 27 | expect_true(is.integer(d$b)) 28 | 29 | d <- select_data(x, b:f, -d) 30 | expect_true(is.data.frame(d)) 31 | expect_equal(nrow(d), 26) 32 | expect_equal(ncol(d), 4) 33 | expect_true(is.numeric(d$c)) 34 | expect_true(!"d" %in% names(d)) 35 | expect_true(is.integer(d$b)) 36 | expect_true(is.logical(d$f)) 37 | expect_true(is.logical(d$e)) 38 | }) 39 | -------------------------------------------------------------------------------- /tests/testthat/test-tbl.R: -------------------------------------------------------------------------------- 1 | context("test-tbl") 2 | 3 | test_that("as_tbl_data, tabsort, ntbl", { 4 | env <- environment() 5 | e <- data.frame( 6 | a = letters, 7 | b = LETTERS, 8 | c = seq_along(letters), 9 | d = data.frame(aa = letters, bb = LETTERS, cc = seq_along(letters)), 10 | row.names = rev(letters) 11 | ) 12 | d <- data.frame(abc = sample(letters[1:3], 100, replace = TRUE), 13 | xyz = sample(letters[24:26], 100, replace = TRUE), 14 | stringsAsFactors = FALSE) 15 | env_tbls(env) 16 | expect_true(inherits(d, "tbl_df")) 17 | expect_true(inherits(e, "tbl_df")) 18 | e <- data.frame( 19 | a = letters, 20 | b = LETTERS, 21 | c = seq_along(letters), 22 | d = data.frame(aa = letters, bb = LETTERS, cc = seq_along(letters)), 23 | row.names = rev(letters) 24 | ) 25 | d <- data.frame(abc = sample(letters[1:3], 100, replace = TRUE), 26 | xyz = sample(letters[24:26], 100, replace = TRUE), 27 | stringsAsFactors = FALSE) 28 | e <- as_tbl_data(e, row_names = TRUE) 29 | expect_named(e) 30 | expect_true("d.bb" %in% names(e)) 31 | expect_equal(ncol(e), 7) 32 | expect_equal(nrow(e), 26) 33 | expect_true(is.factor(e$d.aa)) 34 | expect_true(is.data.frame(e)) 35 | expect_true(is.character(e$row_names)) 36 | 37 | expect_true(inherits(as_tbl_data(d), "tbl_df")) 38 | d <- tabsort(d) 39 | expect_equal(ncol(d), 4) 40 | expect_true(inherits(d, "tbl_df")) 41 | expect_true(inherits(as_tbl_data(d), "tbl_df")) 42 | expect_true(is.data.frame((ntbl(d, n)))) 43 | expect_equal(ncol(ntbl(d, n)), 2) 44 | 45 | expect_true(is.data.frame( 46 | expect_warning( 47 | tabsort(.data = sample(c("a", "b", "c"), nrow(e), replace = TRUE), 48 | n = sample(c("a", "b", "c"), nrow(e), replace = TRUE)) 49 | ) 50 | )) 51 | expect_error(tabsort(prop = 'a')) 52 | }) 53 | 54 | test_that("filter_data, arrange_data", { 55 | set.seed(12) 56 | d <- data.frame(abc = sample(letters[1:3], 100, replace = TRUE), 57 | xyz = sample(letters[24:26], 100, replace = TRUE), 58 | stringsAsFactors = FALSE) 59 | expect_true(is.data.frame(filter_data(d, d$abc == "a"))) 60 | expect_equal(nrow(filter_data(d, d$abc == "a")), 34) 61 | expect_equal(ncol(filter_data(d, d$abc == "a")), 2) 62 | d <- arrange_data(d, decr(abc), decr(xyz)) 63 | expect_true(is.data.frame(d)) 64 | expect_true(max(which(d$abc == "c")) < min(which(d$abc == "a"))) 65 | expect_true( 66 | min(which(d$abc == "c" & d$xyz == "x")) > 67 | max(which(d$abc == "c" & d$xyz == "z")) 68 | ) 69 | expect_equal(nrow(d), 100) 70 | }) 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /tests/testthat/test-tbl_frame.R: -------------------------------------------------------------------------------- 1 | context("test-tbl_frame") 2 | 3 | test_that("multiplication works", { 4 | set.seed(12) 5 | d <- tbl_data_frame( 6 | a = rnorm(10), 7 | b = rnorm(10) 8 | ) 9 | expect_equal(ncol(d), 2) 10 | expect_true(!identical(d[[1]], d[[2]])) 11 | 12 | d <- tbl_data_frame( 13 | a = rnorm(10), 14 | b = rnorm(10), 15 | c = (a + b) / 2, 16 | d = a + b + c 17 | ) 18 | expect_equal(ncol(d), 4) 19 | expect_true(identical(rowMeans(d[, 1:2]), d$c)) 20 | expect_true(identical(round(rowSums(d[, 1:3]), 4), round(d$d, 4))) 21 | }) 22 | --------------------------------------------------------------------------------