Label virtual corpora by the names they were given
Passing c(before = ..., since = ...) said what the two corpora are to be
called, and only collocationAnalysis() listened. frequencyQuery() dropped
the names in the expand_grid() it builds its queries from and returned no
label at all; corpusStats() let them become row names, which the first
bind_rows() throws away; collocationScoreQuery() ignored them and derived
a label from the corpus definitions instead, so that the pair above came
out as "1990 & pubDat..." and "2010".
All three now prefer the names, falling back to queryStringToLabel()
where a vector is named only in part, as collocationAnalysis() has been
doing. A vector without names is left alone: no label column appears
where there is nothing to put in it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I72c7c8d5f14b649df853cae94a4d90c0be19d1f4
diff --git a/R/KorAPCorpusStats.R b/R/KorAPCorpusStats.R
index fcd77df..6fe44d8 100644
--- a/R/KorAPCorpusStats.R
+++ b/R/KorAPCorpusStats.R
@@ -75,6 +75,9 @@
verbose = kco@verbose,
as.df = FALSE) {
if (length(vc) > 1) {
+ # the names of a named vc vector would end up as row names, which the first
+ # bind_rows() drops, so they are kept as a column instead
+ vcLabel <- vcLabels(vc)
# ETA calculation for multiple virtual corpora
total_items <- length(vc)
start_time <- Sys.time()
@@ -94,6 +97,9 @@
# Process current virtual corpus
result <- corpusStats(kco, current_vc, verbose = FALSE, as.df = TRUE)
+ if (!is.null(vcLabel)) {
+ result <- tibble::add_column(result, label = vcLabel[i], .after = "vc")
+ }
results[[i]] <- result
# Record individual processing time
@@ -149,7 +155,9 @@
))
}
- do.call(rbind, results)
+ stats <- do.call(rbind, results)
+ rownames(stats) <- NULL
+ stats
} else {
url <-
paste0(
diff --git a/R/KorAPQuery.R b/R/KorAPQuery.R
index a8372e3..77774c8 100644
--- a/R/KorAPQuery.R
+++ b/R/KorAPQuery.R
@@ -215,14 +215,20 @@
as.df = FALSE,
context = NULL) {
if (length(query) > 1 || length(vc) > 1) {
+ # expand_grid() and tibble() drop the names of vc, so the labels the
+ # caller gave their virtual corpora are carried along as a column
+ vcLabel <- vcLabels(vc)
grid <- if (expand) expand_grid(query = query, vc = vc) else tibble(query = query, vc = vc)
+ if (!is.null(vcLabel)) {
+ grid$label <- if (expand) rep(vcLabel, times = length(query)) else vcLabel
+ }
# Initialize timing variables for ETA calculation
total_queries <- nrow(grid)
current_query <- 0
start_time <- Sys.time()
- results <- purrr::pmap(grid, function(query, vc, ...) {
+ results <- purrr::pmap(grid, function(query, vc, label = NULL, ...) {
current_query <<- current_query + 1
# Execute the single query directly (avoiding recursive call)
@@ -297,6 +303,9 @@
webUIRequestUrl = webUIRequestUrl,
stringsAsFactors = FALSE
)
+ if (!is.null(label)) {
+ result <- tibble::add_column(result, label = label, .after = "vc")
+ }
return(result)
})
diff --git a/R/collocationScoreQuery.R b/R/collocationScoreQuery.R
index a79d72f..6f28bc4 100644
--- a/R/collocationScoreQuery.R
+++ b/R/collocationScoreQuery.R
@@ -125,7 +125,9 @@
tibble(
node = node,
collocate = combinations$collocate,
- label = queryStringToLabel(vc)[combinations$vc_index],
+ # the names the caller gave their virtual corpora, where there
+ # are any, rather than a label guessed from the definitions
+ label = vcLabelsOrGuess(vc)[combinations$vc_index],
vc = combinations$vc,
query = query,
webUIRequestUrl = if (is.na(observed[1]))
diff --git a/R/misc.R b/R/misc.R
index 6e7340f..e120ea4 100644
--- a/R/misc.R
+++ b/R/misc.R
@@ -162,6 +162,40 @@
substring(data, leftCommon + 1, nchar(data) - rightCommon)
}
+#' Labels for a vector of virtual corpora
+#'
+#' The names of a named vector are what the caller chose to call their virtual
+#' corpora, so they are what a label should say. Where a vector is named only in
+#' part, [queryStringToLabel()] derives the rest from the definitions.
+#'
+#' @param vc character vector of virtual corpus definitions
+#' @return character vector of labels, or `NULL` if `vc` carries no names at all
+#' @noRd
+vcLabels <- function(vc) {
+ labels <- names(vc)
+ if (is.null(labels)) {
+ return(NULL)
+ }
+ unnamed <- is.na(labels) | !nzchar(labels)
+ if (any(unnamed)) {
+ labels[unnamed] <- queryStringToLabel(vc)[unnamed]
+ }
+ unname(labels)
+}
+
+#' Labels for a vector of virtual corpora, always giving one
+#'
+#' Like [vcLabels()], but falling back to [queryStringToLabel()] where the
+#' vector carries no names, for callers that label unconditionally.
+#'
+#' @param vc character vector of virtual corpus definitions
+#' @return character vector of labels, one per element of `vc`
+#' @noRd
+vcLabelsOrGuess <- function(vc) {
+ labels <- vcLabels(vc)
+ if (is.null(labels)) queryStringToLabel(vc) else labels
+}
+
## Mute notes: "Undefined global functions or variables:"
globalVariables(c("conf.high", "conf.low", "onRender", "webUIRequestUrl"))