Nothing
.format_one <- function(terms, tags, format) {
switch(
format,
"vector" = stats::setNames(tags, terms),
"data.frame" = data.frame(
term = terms,
tag = tags
),
"legacy" = stats::setNames(terms, tags)
)
}
#' Tag text with a jiebaRS worker
#'
#' Tag one or more strings with a `jieba_worker` created by [worker()].
#'
#' @details
#' `format` controls the shape of each single-string tagging result:
#' - `"vector"`: a named character vector with token names and tag values.
#' - `"data.frame"`: a data frame with `term` and `tag` columns.
#' - `"legacy"`: the old `jiebaR` layout with token values and tag names.
#'
#' In the current release benchmarks on the bundled *Fortress Besieged* and
#' *Dream of the Red Chamber* texts, `jiebaRS::tagging()` is about **1.6x to
#' 1.8x faster** than `jiebaR::tagging()` when each novel is tagged as one long
#' string. When the same content is split into many strings and processed in
#' batch, `jiebaRS::tagging()` is about **2x to 5x faster** than `jiebaR`.
#'
#' For very long texts, splitting before tagging is usually faster than sending
#' one huge string. In the same release benchmarks, the best results appeared
#' around **32 to 128 chunks**, while much finer splitting still helped but was
#' no longer optimal.
#'
#' When `code` contains multiple strings, `batch` controls how the per-string
#' results are aggregated:
#' - `"list"`: one single-string result per input string.
#' - `"flatten"`: concatenate all results into one. The shape is decided by
#' `format`: `"vector"`/`"legacy"` produce a named character vector, while
#' `"data.frame"` produces a combined data frame with a `doc_id` column.
#'
#' When `batch` is omitted, `jiebaRS` returns `"vector"` for single-string
#' input and `"list"` for multi-string input.
#'
#' @param code A non-empty character vector to tag.
#' @param jiebar A `jieba_worker` object created with `worker(type = "tag")`.
#' @param ... Must be empty. This enforces that optional arguments such as
#' `format` and `batch` are supplied with explicit names.
#' @param format Output format for a single tagged string. Must be one of
#' `"vector"`, `"data.frame"`, or `"legacy"`.
#' @param batch Aggregation mode for multi-string input. Must be one of
#' `"list"` or `"flatten"`.
#'
#' @return Tagging results in the requested format.
#' @examples
#' tagger <- worker(type = "tag")
#' text1 <- "\u8fd9\u662f\u4e00\u4e2a\u6d4b\u8bd5"
#' text2 <- "\u518d\u6765\u4e00\u6b21"
#' tagging(text1, tagger)
#' tagging(c(text1, text2), tagger)
#' tagging(c(text1, text2), tagger, format = "data.frame", batch = "flatten")
#' @export
tagging <- function(
code,
jiebar,
...,
format = c("vector", "data.frame", "legacy"),
batch = c("list", "flatten")
) {
rlang::check_dots_empty()
if (!inherits(jiebar, "jieba_tagger")) {
cli::cli_abort(
r"(`jiebar` must be a `jieba_tagger` object created with `worker(type = "tag")`.)"
)
}
if (!rlang::is_character(code) || anyNA(code) || rlang::is_empty(code)) {
cli::cli_abort("`code` must be a non-empty character vector without missing values.")
}
format <- rlang::arg_match(format, c("vector", "data.frame", "legacy"))
code <- enc2utf8(code)
code <- symbol_handle(code, jiebar$config$symbol)
is_single <- length(code) == 1L
result <- if (is_single) {
tagging_worker(code[[1]], jiebar$ptr)
} else {
tagging_batch_worker(code, jiebar$ptr)
}
if (is_single) {
return(.format_one(result$term, result$tag, format))
}
batch <- rlang::arg_match(batch)
if (identical(batch, "list")) {
return(lapply(result, function(x) .format_one(x$term, x$tag, format)))
}
terms_list <- lapply(result, .subset2, "term")
tags_list <- lapply(result, .subset2, "tag")
all_terms <- unlist(terms_list, use.names = FALSE)
all_tags <- unlist(tags_list, use.names = FALSE)
if (identical(format, "data.frame")) {
return(data.frame(
doc_id = rep.int(seq_along(result), lengths(terms_list)),
term = all_terms,
tag = all_tags
))
}
.format_one(all_terms, all_tags, format)
}
#' Tag a batch of strings
#'
#' Convenience wrapper around [tagging()] for multi-string input. When `batch`
#' is not supplied, `tagging_batch()` always returns list output.
#'
#' @details
#' `tagging_batch()` is a convenience wrapper for explicit multi-string input.
#' The returned object depends on both `format` and `batch`:
#' - `batch = "list"`: returns one single-string tagging result per input
#' string.
#' - `batch = "flatten"`: concatenates all results into one. The shape is
#' decided by `format`: `"vector"`/`"legacy"` produce a named character
#' vector, while `"data.frame"` produces a combined data frame with a
#' `doc_id` column.
#'
#' In the current release benchmarks on the bundled *Fortress Besieged* and
#' *Dream of the Red Chamber* texts, batch tagging is about **2x to 5x faster**
#' than the comparable `jiebaR` workflow on many-string inputs. For very long
#' texts, the best throughput was usually reached by splitting into about **32
#' to 128 chunks**, while much finer splitting still helped but was no longer
#' optimal.
#'
#' @param texts A non-empty character vector to tag.
#' @param jiebar A `jieba_worker` object created with `worker(type = "tag")`.
#' @param ... Must be empty. This enforces that optional arguments such as
#' `format` and `batch` are supplied with explicit names.
#' @param format Output format for each single tagged result. Must be one of
#' `"vector"`, `"data.frame"`, or `"legacy"`.
#' @param batch Aggregation mode. Must be one of `"list"` or `"flatten"`.
#'
#' @return Tagging results in the requested format.
#' @examples
#' tagger <- worker(type = "tag")
#' texts <- c("\u8fd9\u662f\u4e00\u4e2a\u6d4b\u8bd5", "\u518d\u6765\u4e00\u6b21")
#' tagging_batch(texts, tagger)
#' tagging_batch(texts, tagger, format = "legacy", batch = "flatten")
#' @export
tagging_batch <- function(
texts,
jiebar,
...,
format = c("vector", "data.frame", "legacy"),
batch = c("list", "flatten")
) {
rlang::check_dots_empty()
format <- rlang::arg_match(format, c("vector", "data.frame", "legacy"))
batch <- rlang::arg_match(batch, c("list", "flatten"))
tagging(texts, jiebar, format = format, batch = batch)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.