% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/cooccurrence.R
\name{cooccurrence}
\alias{cooccurrence}
\alias{co}
\title{Build a co-occurrence network}
\usage{
cooccurrence(
  data,
  field = NULL,
  by = NULL,
  sep = NULL,
  weight_by = NULL,
  split_by = NULL,
  similarity = c("none", "jaccard", "cosine", "inclusion", "association", "dice",
    "equivalence", "relative"),
  counting = c("full", "fractional"),
  scale = NULL,
  threshold = 0,
  min_occur = 1L,
  top_n = NULL,
  output = c("default", "gephi", "igraph", "cograph", "matrix"),
  ...
)

co(
  data,
  field = NULL,
  by = NULL,
  sep = NULL,
  weight_by = NULL,
  split_by = NULL,
  similarity = c("none", "jaccard", "cosine", "inclusion", "association", "dice",
    "equivalence", "relative"),
  counting = c("full", "fractional"),
  scale = NULL,
  threshold = 0,
  min_occur = 1L,
  top_n = NULL,
  output = c("default", "gephi", "igraph", "cograph", "matrix"),
  ...
)
}
\arguments{
\item{data}{Input data. Accepts:
\itemize{
\item A \code{data.frame} with a delimited column (\code{field} + \code{sep}).
\item A \code{data.frame} in long/bipartite format (\code{field} + \code{by}).
\item A binary (0/1) \code{data.frame} or \code{matrix} (auto-detected).
\item A wide sequence \code{data.frame} or \code{matrix} (non-binary).
\item A \code{list} of character vectors (each element is a transaction).
}}

\item{field}{Character. The entity column --- determines what the nodes are.
For delimited format, a single column split by \code{sep}. For
long/bipartite, the item column. For multi-column delimited, a vector
of column names pooled per row. Use \code{field = "all"} for wide
sequence data (e.g. TraMineR / tna format) where every column is a
time point and cell values are the items.}

\item{by}{Character or \code{NULL}. Grouping column for long/bipartite
format. Each unique value defines one transaction.}

\item{sep}{Character or \code{NULL}. Separator for splitting delimited
fields.}

\item{weight_by}{Character or \code{NULL}. Column name containing a numeric
association strength for each entity-transaction pair. Only accepted for
long format (\code{field} + \code{by}). When supplied, each entity
contributes its weight rather than 1, so
\eqn{C_{ij} = \sum_d w_{id} \cdot w_{jd}}.
Typical use: topic-document probability matrices from LDA or similar
models.}

\item{split_by}{Character or \code{NULL}. Column name to split the data
by before computing co-occurrence. A separate network is computed per
group and the results are combined into a single data frame with an
additional \code{group} column. Only works with data.frame inputs.}

\item{similarity}{Character. Similarity measure:
\describe{
\item{\code{"none"}}{Raw co-occurrence counts.}
\item{\code{"jaccard"}}{\eqn{C_{ij} / (f_i + f_j - C_{ij})}.}
\item{\code{"cosine"}}{Salton's cosine:
\eqn{C_{ij} / \sqrt{f_i \cdot f_j}}.}
\item{\code{"inclusion"}}{Simpson coefficient:
\eqn{C_{ij} / \min(f_i, f_j)}.}
\item{\code{"association"}}{Association strength:
\eqn{C_{ij} / (f_i \cdot f_j)}
(van Eck & Waltman, 2009).}
\item{\code{"dice"}}{\eqn{2 C_{ij} / (f_i + f_j)}.}
\item{\code{"equivalence"}}{Salton's cosine squared:
\eqn{C_{ij}^2 / (f_i \cdot f_j)}.}
\item{\code{"relative"}}{Row-normalized: each row sums to 1.}
}}

\item{counting}{Character. Counting method:
\describe{
\item{\code{"full"}}{Each co-occurring pair adds 1 regardless of
transaction size. Default.}
\item{\code{"fractional"}}{Each pair adds \eqn{1 / (n_i - 1)}
where \eqn{n_i} is the number of items in transaction \eqn{i}.
Transactions with many items contribute less per pair
(Perianes-Rodriguez et al., 2016).}
}}

\item{scale}{Character or \code{NULL}. Optional scaling applied to weights
after similarity normalization:
\describe{
\item{\code{NULL} or \code{"none"}}{No scaling.}
\item{\code{"minmax"}}{Min-max to \eqn{[0, 1]}.}
\item{\code{"log"}}{Natural log: \eqn{\log(1 + w)}.}
\item{\code{"log10"}}{Log base 10: \eqn{\log_{10}(1 + w)}.}
\item{\code{"binary"}}{Binary: 1 if \eqn{w > 0}, else 0.}
\item{\code{"zscore"}}{Z-score standardization.}
\item{\code{"sqrt"}}{Square root.}
\item{\code{"proportion"}}{Divide by sum of all weights.}
}}

\item{threshold}{Numeric. Minimum edge weight to retain. Applied after
similarity and scaling. Default 0.}

\item{min_occur}{Integer. Minimum entity frequency. Entities appearing in
fewer than \code{min_occur} transactions are dropped. Default 1.}

\item{top_n}{Integer or \code{NULL}. Keep only the top \code{top_n} edges
by weight. When \code{split_by} is used, applied per group.
Default \code{NULL} (all edges).}

\item{output}{Character. Column naming convention for the output:
\describe{
\item{\code{"default"}}{\code{from}, \code{to}, \code{weight}, \code{count}.}
\item{\code{"gephi"}}{\code{Source}, \code{Target}, \code{Weight},
\code{Type} (= \code{"Undirected"}). Ready for Gephi import.}
\item{\code{"igraph"}}{Returns an \code{igraph} graph object directly.}
\item{\code{"cograph"}}{Returns a \code{cograph_network} object directly.}
\item{\code{"matrix"}}{Returns the square co-occurrence matrix.}
}}

\item{...}{Currently unused.}
}
\value{
Depends on \code{output}:
\itemize{
\item \code{"default"}: A \code{cooccurrence} data frame with columns
\code{from}, \code{to}, \code{weight}, \code{count} (and \code{group}
when \code{split_by} is used).
\item \code{"gephi"}: A data frame with columns \code{Source},
\code{Target}, \code{Weight}, \code{Type}, \code{Count}. Ready for
Gephi CSV import.
\item \code{"igraph"}: An \code{igraph} graph object.
\item \code{"cograph"}: A \code{cograph_network} object.
\item \code{"matrix"}: A square numeric co-occurrence matrix.
}
For the data frame outputs, rows are sorted by weight descending and
attributes store the full matrix, item frequencies, and parameters.
}
\description{
Constructs an undirected co-occurrence network from various input formats
and returns a tidy edge data frame. Argument names follow the citenets
convention.
}
\examples{
# Delimited keywords
df <- data.frame(
  id = 1:4,
  keywords = c("network; graph", "graph; matrix; network",
               "matrix; algebra", "network; algebra; graph")
)
cooccurrence(df, field = "keywords", sep = ";")

# Split by a grouping variable
df$year <- c(2020, 2020, 2021, 2021)
cooccurrence(df, field = "keywords", sep = ";", split_by = "year")

# List of transactions with Jaccard similarity
cooccurrence(list(c("A","B","C"), c("B","C"), c("A","C")),
             similarity = "jaccard")

# Short alias
co(df, field = "keywords", sep = ";", similarity = "cosine")

# Weighted long format (e.g. LDA topic-document probabilities)
theta <- data.frame(
  doc   = c("d1","d1","d1","d2","d2","d3","d3"),
  topic = c("T1","T2","T3","T1","T3","T2","T3"),
  prob  = c(0.6, 0.3, 0.1, 0.4, 0.6, 0.5, 0.5)
)
cooccurrence(theta, field = "topic", by = "doc", weight_by = "prob")

}
\references{
van Eck, N. J., & Waltman, L. (2009). How to normalize co-occurrence
data? An analysis of some well-known similarity measures. \emph{Journal of
the American Society for Information Science and Technology}, 60(8),
1635--1651.
}
