% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/completeMetadata.R
\name{completeMetadata}
\alias{completeMetadata}
\title{Complete missing metadata via DOI lookup against Crossref and OpenAlex}
\usage{
completeMetadata(
  M,
  sources = c("openalex", "crossref"),
  fields = c("AB", "AU", "C1", "CR", "DT", "LA", "PY", "RP", "SO", "TC", "TI"),
  email = NULL,
  oa_apikey = NULL,
  batch_size = 20,
  max_records = Inf,
  progress = NULL,
  verbose = TRUE
)
}
\arguments{
\item{M}{Bibliometrix data frame produced by \code{\link{convert2df}}.}

\item{sources}{Character vector of enrichment sources.
Default \code{c("openalex", "crossref")}. Order is irrelevant; OpenAlex
always runs before Crossref. \code{"openalex"} is skipped if
\code{M$DB[1] == "OPENALEX"}.}

\item{fields}{Character vector of WoS-codified fields to attempt to fill.
Default \code{c("AB","AU","C1","CR","DT","LA","PY","RP","SO","TC","TI")}.
\code{TC} is filled only by OpenAlex.}

\item{email}{Optional contact email used as the Crossref polite-pool
identifier and OpenAlex \code{mailto}. If \code{NULL}, the function
falls back to the env var \code{BIBLIOMETRIX_EMAIL} or the persisted
file \code{~/.biblio_openalex_email.txt}.}

\item{oa_apikey}{Optional OpenAlex API key. If \code{NULL}, the function
reads \code{Sys.getenv("openalexR.apikey")} and falls back to
\code{~/.biblio_openalex_apikey.txt}. The OpenAlex pass works without a
key (lower rate limit).}

\item{batch_size}{Number of DOIs per Crossref batch request (default 20).
OpenAlex uses a fixed batch size of 50 (the maximum that keeps URLs
under length limits).}

\item{max_records}{Optional cap on the number of records to enrich
(useful for previewing). Default \code{Inf}.}

\item{progress}{Optional callback \code{function(done, total, label)}
invoked after each batch. Used by biblioshiny to drive a progress bar.}

\item{verbose}{Logical. Print progress messages to the console.}
}
\value{
A list with components:
\describe{
  \item{\code{M}}{The enriched collection (same class as the input).}
  \item{\code{report}}{Long-format \code{data.frame} with one row per
    (field, source) summarising attempts, fills, and failures.}
  \item{\code{before}}{The \code{mandatoryTags} table from
    \code{missingData(M)} before enrichment.}
  \item{\code{after}}{The \code{mandatoryTags} table from
    \code{missingData(M)} after enrichment.}
}
Provenance is attached to the returned collection as
\code{attr(M, "enrichment")}, a long-format \code{data.frame} with columns
\code{SR}, \code{field}, \code{source}, \code{timestamp}.
}
\description{
Given a bibliometrix collection produced by \code{\link{convert2df}}, this
function takes the subset of records that have a DOI but are missing one
or more of the analysis-relevant fields, queries the Crossref REST API
(\url{https://api.crossref.org/works}) and/or OpenAlex (via
\pkg{openalexR}) using the DOI as the lookup key, and fills the gaps
with the values returned by those sources. Existing non-empty values
are never overwritten.
}
\details{
When both sources are enabled, OpenAlex runs first (broader coverage of
AB/CR/C1/TC) and Crossref then fills the residual gaps. If the input
collection was originally imported from OpenAlex (\code{M$DB[1] ==
"OPENALEX"}), the OpenAlex pass is automatically skipped because re-querying
it would not add information.

The vacancy predicate matches the one used by \code{\link{missingData}}:
a cell is considered missing when it is \code{NA} or one of
\code{c("", "NA", "none", "NA,0000,NA")}.

Crossref cannot supply author keywords (DE), Keywords Plus (ID), Web of
Science categories (WC), or citation counts (TC). OpenAlex covers TC,
AB, AU, C1, CR, DT, LA, PY, RP, SO, TI well; OpenAlex \code{keywords}
are AI-derived topic labels and not author keywords, so DE is off by
default. ID and WC are always skipped.
}
\examples{
\dontrun{
data(scientometrics, package = "bibliometrixData")
res <- completeMetadata(scientometrics, email = "you@example.com")
res$report
res$after
}

}
