blob: ac7e7d9f511ad8c2dd40c16972eb8649e2e00d8a [file] [log] [blame]
Marc Kupietzdbd431a2021-08-29 12:17:45 +02001% Generated by roxygen2: do not edit by hand
2% Please edit documentation in R/collocationAnalysis.R
3\name{collocationAnalysis,KorAPConnection-method}
4\alias{collocationAnalysis,KorAPConnection-method}
5\alias{collocationAnalysis}
6\title{Collocation analysis}
7\usage{
8\S4method{collocationAnalysis}{KorAPConnection}(
9 kco,
10 node,
11 vc = "",
12 lemmatizeNodeQuery = FALSE,
13 minOccur = 5,
14 leftContextSize = 5,
15 rightContextSize = 5,
16 topCollocatesLimit = 200,
17 searchHitsSampleLimit = 20000,
18 ignoreCollocateCase = FALSE,
19 withinSpan = ifelse(exactFrequencies, "base/s=s", ""),
20 exactFrequencies = TRUE,
Marc Kupietz6505ccf2021-11-27 17:46:25 +010021 stopwords = append(RKorAPClient::synsemanticStopwords(), node),
Marc Kupietzdbd431a2021-08-29 12:17:45 +020022 seed = 7,
23 expand = length(vc) != length(node),
Marc Kupietz5a336b62021-11-27 17:51:35 +010024 maxRecurse = 0,
Marc Kupietzdadfd912021-12-22 12:48:20 +010025 addExamples = FALSE,
Marc Kupietz419f21f2021-12-07 10:27:30 +010026 thresholdScore = "logDice",
27 threshold = 2,
Marc Kupietz5a336b62021-11-27 17:51:35 +010028 localStopwords = c(),
Marc Kupietz47d0d2b2021-12-19 16:38:52 +010029 collocateFilterRegex = "^[:alnum:]+-?[:alnum:]*$",
Marc Kupietz1d400f62026-09-03 14:46:16 +020030 minObservedExpectedRatio = 1,
Marc Kupietzde679ea2025-10-19 13:14:51 +020031 queryMissingScores = FALSE,
Marc Kupietz130a2a22025-10-18 16:09:23 +020032 missingScoreQuantile = 0.05,
33 vcLabel = NA_character_,
Marc Kupietzdb2fabd2026-04-27 15:01:37 +020034 cacheAs = NULL,
Marc Kupietzdbd431a2021-08-29 12:17:45 +020035 ...
36)
37}
38\arguments{
Marc Kupietz617266d2025-02-27 10:43:07 +010039\item{kco}{\code{\link[=KorAPConnection]{KorAPConnection()}} object (obtained e.g. from \code{KorAPConnection()}}
Marc Kupietzdbd431a2021-08-29 12:17:45 +020040
Marc Kupietz209b52c2026-06-21 12:14:36 +020041\item{node}{target word or query as a single character string}
Marc Kupietzdbd431a2021-08-29 12:17:45 +020042
Marc Kupietz209b52c2026-06-21 12:14:36 +020043\item{vc}{character vector describing the virtual corpus or corpora in which the query should be performed. An empty string (default) means the whole corpus, as far as it is license-wise accessible.}
Marc Kupietzdbd431a2021-08-29 12:17:45 +020044
Marc Kupietz67edcb52021-09-20 21:54:24 +020045\item{lemmatizeNodeQuery}{if TRUE, node query will be lemmatized, i.e. \verb{x -> [tt/l=x]}}
Marc Kupietzdbd431a2021-08-29 12:17:45 +020046
47\item{minOccur}{minimum absolute number of observed co-occurrences to consider a collocate candidate}
48
49\item{leftContextSize}{size of the left context window}
50
51\item{rightContextSize}{size of the right context window}
52
53\item{topCollocatesLimit}{limit analysis to the n most frequent collocates in the search hits sample}
54
55\item{searchHitsSampleLimit}{limit the size of the search hits sample}
56
57\item{ignoreCollocateCase}{logical, set to TRUE if collocate case should be ignored}
58
Marc Kupietz6bd9cad2024-12-18 15:57:26 +010059\item{withinSpan}{KorAP span specification (see \url{https://korap.ids-mannheim.de/doc/ql/poliqarp-plus?embedded=true#spans}) for collocations to be searched within. Defaults to \code{base/s=s}.}
Marc Kupietzdbd431a2021-08-29 12:17:45 +020060
61\item{exactFrequencies}{if FALSE, extrapolate observed co-occurrence frequencies from frequencies in search hits sample, otherwise retrieve exact co-occurrence frequencies}
62
63\item{stopwords}{vector of stopwords not to be considered as collocates}
64
65\item{seed}{seed for random page collecting order}
66
67\item{expand}{if TRUE, \code{node} and \code{vc} parameters are expanded to all of their combinations}
68
Marc Kupietz7d400e02021-12-19 16:39:36 +010069\item{maxRecurse}{apply collocation analysis recursively \code{maxRecurse} times}
70
71\item{addExamples}{If TRUE, examples for instances of collocations will be added in a column \code{example}. This makes a difference in particular if \code{node} is given as a lemma query.}
72
Marc Kupietzdb2fabd2026-04-27 15:01:37 +020073\item{thresholdScore}{association score function (see \code{\link{association-score-functions}}) to use for computing the threshold that is applied for recursive collocation analysis calls (only applied when \code{maxRecurse > 0})}
Marc Kupietz7d400e02021-12-19 16:39:36 +010074
Marc Kupietzb6416be2026-09-03 14:37:37 +020075\item{threshold}{minimum value of \code{thresholdScore} function call to apply collocation analysis recursively (only applied when \code{maxRecurse > 0}).
76Note that the default score, \code{logDice}, expresses how salient a pair is
77rather than how surprising, so that a frequent collocate can pass it while
Marc Kupietz1d400f62026-09-03 14:46:16 +020078co-occurring less often than expected. \code{minObservedExpectedRatio} keeps
79those out. See the "Salience versus surprise" section of
80\code{\link{association-score-functions}}.}
Marc Kupietz7d400e02021-12-19 16:39:36 +010081
82\item{localStopwords}{vector of stopwords that will not be considered as collocates in the current function call, but that will not be passed to recursive calls}
83
Marc Kupietz47d0d2b2021-12-19 16:38:52 +010084\item{collocateFilterRegex}{allow only collocates matching the regular expression}
85
Marc Kupietz1d400f62026-09-03 14:46:16 +020086\item{minObservedExpectedRatio}{minimum ratio of observed to expected co-occurrence
87frequency a collocate must reach. Defaults to 1, which keeps only collocates
88that occur at least as often as expected by chance, corresponding to a
89non-negative \code{pmi}. Without it, frequent words can end up among the top
90collocates by \code{logDice} although the node does not attract them at all (see
91the "Salience versus surprise" section of
92\code{\link{association-score-functions}}). Raise it to demand a stronger
93contrast, e.g. 2 for collocates occurring at least twice as often as
94expected, or set it to 0 to switch the filter off and obtain the unfiltered
95result of earlier versions, e.g. in order to study repulsion.}
96
Marc Kupietzde679ea2025-10-19 13:14:51 +020097\item{queryMissingScores}{if TRUE, attempt to retrieve corpus-based association scores for vc/collocate combinations that would otherwise be imputed, by re-querying the KorAP backend without applying the collocate frequency threshold}
98
Marc Kupietz95253342026-08-31 10:18:43 +020099\item{missingScoreQuantile}{lower quantile (evaluated per association measure over the pooled result set) that anchors the adaptive floor used for imputing missing scores between virtual corpora; a robust spread is subtracted from this anchor so the imputed values stay at or below the weakest observed scores. Imputed cells are marked in the \verb{imputed*} columns; see the section on interpreting multi-VC comparisons below}
Marc Kupietz130a2a22025-10-18 16:09:23 +0200100
101\item{vcLabel}{optional label override for the current virtual corpus (used internally when named VC collections are expanded)}
102
Marc Kupietz37f96072026-09-03 07:18:11 +0200103\item{cacheAs}{path to an RDS file for caching the result. If the file already exists, the cached result is loaded and returned immediately without contacting the server. Otherwise the analysis is run normally and the result is saved to the file before returning. Defaults to \code{NULL} (no caching).
104
105The analysis parameters are stored alongside the result. If they differ from
106those of the current call, the cached result would not be the one that was
107asked for, so it is recomputed and the file overwritten, with a warning
108naming the parameters that differ. Pass a different \code{cacheAs} file name
109to keep an existing analysis. Cache files written by RKorAPClient 1.3.0 do
110not contain the parameters yet and are used as they are.}
Marc Kupietzdb2fabd2026-04-27 15:01:37 +0200111
Marc Kupietz67edcb52021-09-20 21:54:24 +0200112\item{...}{more arguments will be passed to \code{\link[=collocationScoreQuery]{collocationScoreQuery()}}}
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200113}
114\value{
Marc Kupietz130a2a22025-10-18 16:09:23 +0200115A tibble where each row represents a candidate collocate for the requested node.
116Columns include (depending on the selected association measures):
117
118\itemize{
119\item \code{node}, \code{collocate}, \code{vc}, \code{label}: identifiers for the query node, collocate, virtual corpus, and optional label.
120\item Frequency and contingency information such as \code{frequency}, \code{O}, \code{O1}, \code{O2}, \code{E}, \code{leftContextSize}, \code{rightContextSize}, and \code{w}.
121\item Association measures (e.g. \code{logDice}, \code{ll}, \code{mi}, ...), one column per requested scorer.
122\item Per-labelled association scores produced by multi-VC comparisons using the pattern \code{<measure>_<label>}.
123\item Ranks per label/measure with the pattern \code{rank_<label>_<measure>} (1 is best) and the corresponding percentile ranks \code{percentile_rank_<label>_<measure>}.
124\item Pairwise contrasts for two-label comparisons, e.g. \code{delta_<measure>}, \code{delta_rank_<measure>}, and \code{delta_percentile_rank_<measure>}.
Marc Kupietz09b1c082026-05-01 14:45:47 +0200125\item Summary columns describing the strongest labels per measure (\code{winner_*}, \code{runner_up_*}, \code{loser_*}, and \code{max_delta_*}), including winner/loser \code{webUIRequestUrl} columns. In multi-VC comparisons, missing per-label concordance URLs are derived from another available row URL for the same \code{node}/\code{collocate} by replacing the \code{cq} parameter with the target label's virtual corpus. Unsuffixed \code{winner_webUIRequestUrl} and \code{loser_webUIRequestUrl} columns are populated only when the score-based URL choices agree.
Marc Kupietzd7bb5cb2026-08-31 10:18:02 +0200126\item \code{imputed_<label>}, \code{n_imputed}, and \code{imputed}: flags marking rows whose scores were not observed for some label but imputed (see \code{missingScoreQuantile}). Filter with \code{dplyr::filter(!imputed)} to keep only collocates attested in every compared virtual corpus.
Marc Kupietz130a2a22025-10-18 16:09:23 +0200127\item Optional helper columns such as \code{query}, \code{example}, or \code{url} when example retrieval is requested.
128}
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200129}
130\description{
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200131Performs a collocation analysis for the given node (or query)
132in the given virtual corpus.
133}
134\details{
135The collocation analysis is currently implemented on the client side, as some of the
136functionality is not yet provided by the KorAP backend. Mainly for this reason
137it is very slow (several minutes, up to hours), but on the other hand very flexible.
138You can, for example, perform the analysis in arbitrary virtual corpora, use complex node queries,
139and look for expression-internal collocates using the focus function (see examples and demo).
140
141To increase speed at the cost of accuracy and possible false negatives,
142you can decrease searchHitsSampleLimit and/or topCollocatesLimit and/or set exactFrequencies to FALSE.
143
Marc Kupietze7f0d682025-02-19 10:50:59 +0100144Note that some outdated non-DeReKo back-ends might not yet support returning tokenized matches (warning issued).
145In this case, the client library will fall back to client-side tokenization which might be slightly less accurate.
146This might lead to false negatives and to frequencies that differ from corresponding ones acquired via the web
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200147user interface.
148}
Marc Kupietz95253342026-08-31 10:18:43 +0200149\section{Interpreting multi-VC comparisons}{
150
151
Marc Kupietzba15cff2026-08-31 10:19:56 +0200152\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}}
153
154The comparison columns produced when \code{vc} holds more than one virtual corpus
155are experimental: their names and semantics may still change in a future
156release without a deprecation cycle. Code that has to keep working across
157versions should select the columns it needs explicitly.
158
159They are an exploration aid, not a significance test. When reading them, keep
160three properties in mind.
Marc Kupietz95253342026-08-31 10:18:43 +0200161
162\strong{Imputed scores describe presence/absence, not contrast.} A collocate
163that passes the \code{minOccur} and \code{topCollocatesLimit} thresholds in one virtual
164corpus but not in another has no observed score for the latter. Such cells are
165imputed from a floor derived from the pooled result set (see
166\code{missingScoreQuantile}), so the corresponding \verb{delta_*} and \verb{max_delta_*}
167values measure the distance to that floor rather than an attested difference.
168The \code{imputed}, \code{n_imputed} and \verb{imputed_<label>} columns mark these rows;
169\code{dplyr::filter(!imputed)} restricts the result to collocates attested
170everywhere, and \code{queryMissingScores = TRUE} replaces most imputed cells with
171scores actually retrieved from the backend.
172
173\strong{Imputed values are relative to one analysis.} The floor is computed
174from the scores present in the result at hand. Analysing a node on its own and
175analysing it together with other nodes therefore yield different imputed
176values, and deltas involving imputed cells are not comparable across separate
177calls. Deltas between observed scores are unaffected.
178
179\strong{Winners carry no uncertainty.} Unlike \code{\link[=ci]{ci()}}, which attaches
180confidence intervals to relative frequencies, the \verb{winner_*} / \verb{loser_*}
181columns simply order point estimates. A collocate wins by a hair on six
182occurrences exactly as decisively as one that wins by a wide margin on
183thousands. Consult the observed frequencies (\code{O}, \code{O1}, \code{O2}) and the
184\code{webUIRequestUrl} concordance links before drawing conclusions from a
185small difference.
186
187Note also that \verb{rank_<label>_<measure>} and
188\verb{percentile_rank_<label>_<measure>} are computed within each label, over that
189label's own candidate set. Candidate sets usually differ in size between
190virtual corpora, so rank-based deltas compare positions in populations of
191different sizes.
192}
193
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200194\examples{
Marc Kupietz6ae76052021-09-21 10:34:00 +0200195\dontrun{
196
Marc Kupietzb1dec012025-06-04 17:16:57 +0200197# Find top collocates of "Packung" inside and outside the sports domain.
198KorAPConnection(verbose = TRUE) |>
199 collocationAnalysis("Packung",
200 vc = c("textClass=sport", "textClass!=sport"),
201 leftContextSize = 1, rightContextSize = 1, topCollocatesLimit = 20
202 ) |>
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200203 dplyr::filter(logDice >= 5)
204}
205
Marc Kupietz6ae76052021-09-21 10:34:00 +0200206\dontrun{
207
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200208# Identify the most prominent light verb construction with "in ... setzen".
209# Note that, currently, the use of focus function disallows exactFrequencies.
Marc Kupietz463bb162025-03-26 10:23:33 +0100210KorAPConnection(verbose = TRUE) |>
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200211 collocationAnalysis("focus(in [tt/p=NN] {[tt/l=setzen]})",
Marc Kupietzb1dec012025-06-04 17:16:57 +0200212 leftContextSize = 1, rightContextSize = 0, exactFrequencies = FALSE, topCollocatesLimit = 20
213 )
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200214}
215
216}
217\seealso{
Marc Kupietz209b52c2026-06-21 12:14:36 +0200218Other collocation analysis functions:
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200219\code{\link{association-score-functions}},
220\code{\link{collocationScoreQuery,KorAPConnection-method}},
Marc Kupietz209b52c2026-06-21 12:14:36 +0200221\code{\link[=synsemanticStopwords]{synsemanticStopwords()}}
Marc Kupietzdbd431a2021-08-29 12:17:45 +0200222}
223\concept{collocation analysis functions}