R/count.R

Defines functions duckplyr_count count.duckplyr_df

# Generated by 02-duckplyr_df-methods.R
#' @export
count.duckplyr_df <- function(x, ..., wt = NULL, sort = FALSE, name = NULL, .drop = group_by_drop_default(x)) {
  force(x)

  dplyr_local_error_call()

  by <- dplyr_quosures(...)
  by <- fix_auto_name(by)

  by_exprs <- unname(map(by, quo_get_expr))
  is_name <- map_lgl(by_exprs, is_symbol)

  # For better error message
  if (!is.null(name)) {
    check_string(name, call = dplyr_error_call())
  }

  # Passing `name` reliably is surprisingly complicated.
  rel_try(list(name = "count", x = x, args = try_list(dots = enquos(...), wt = enquo(wt), sort = sort, .drop = .drop)),
    "count() needs all(is_name)" = !all(is_name),
    "count() only implemented for .drop = TRUE" = !.drop,
    "count() only implemented for sort = FALSE" = sort,
    {
      rel <- duckdb_rel_from_df(x)

      by_chr <- map_chr(by_exprs, as_string)
      name_was_null <- is.null(name)
      name <- check_n_name(name, by_chr, call = dplyr_error_call())

      if (name %in% by_chr) {
        cli::cli_abort("Name clash in `count()`")
      }
      n <- tally_n(x, {{ wt }})

      groups <- rel_translate_dots(by, x)
      aggregates <- list(rel_translate(n, x, alias = name))

      out_rel <- rel_aggregate(rel, groups, unname(aggregates))
      if (length(groups) > 0) {
        sort_cols <- nexprs(names(groups))
        out_rel <- rel_order(out_rel, sort_cols)
      }

      out <- rel_to_df(out_rel)
      out <- dplyr_reconstruct(out, x)

      return(out)
    }
  )

  # FIXME: optimize, no need to forward dots
  # out <- count(x_df, !!!quos, wt = {{ wt }}, sort = sort, name = name, .drop = .drop)

  # dplyr forward
  count <- dplyr$count.data.frame
  out <- count(x, ..., wt = {{ wt }}, sort = sort, name = name, .drop = .drop)
  return(out)

  # dplyr implementation
  dplyr_local_error_call()

  if (!missing(...)) {
    out <- group_by(x, ..., .add = TRUE, .drop = .drop)
  } else {
    out <- x
  }

  out <- tally(out, wt = !!enquo(wt), sort = sort, name = name)

  # Ensure grouping is transient
  out <- dplyr_reconstruct(out, x)

  out
}

duckplyr_count <- function(x, ...) {
  try_fetch(
    x <- as_duckplyr_df(x),
    error = function(e) {
      testthat::skip(conditionMessage(e))
    }
  )
  out <- count(x, ...)
  class(out) <- setdiff(class(out), "duckplyr_df")
  out
}
duckdblabs/duckplyr documentation built on Nov. 6, 2024, 10 p.m.