Skip to contents

Calculates the Citation Cycle Time (CCT) to measure the pace of scientific or technological progress in a publication network. Based on Kayal (1999), the indicator measures the median age of cited publications, where lower values indicate faster knowledge replacement cycles.

Usage

sniff_citations_cycle_time(
  network,
  scope = "groups",
  start_year = NULL,
  end_year = NULL,
  tracked_cr_py = NULL,
  batch_size = 50,
  min_papers_per_year = 3,
  rolling_window = NULL
)

Arguments

network

Required. Network object containing publication data. For scope = "groups": object returned by sniff_groups(). For scope = "network": network object (tbl_graph or igraph).

scope

Analysis scope. Either "groups" (default) for separate group analysis or "network" for complete network analysis.

start_year, end_year

Start and end years for temporal analysis. If not specified, uses minimum and maximum years found in the data.

tracked_cr_py

Pre-processed citation year data (optional). A tibble with columns CR (OpenAlex work ID) and CR_PY (publication year). If provided, skips fetching data from OpenAlex API. Useful for avoiding repeated API calls.

batch_size

For OpenAlex data: number of IDs to process per API call (default: 50). Smaller batches help avoid API rate limits, larger batches process data faster but may trigger rate limiting.

min_papers_per_year

Minimum number of papers required in a given year to compute CCT. Years with fewer papers are reported as NA (default: 3).

rolling_window

Optional integer for rolling window smoothing. If provided, CCT values are smoothed using a centered moving average of the specified width (e.g., 3 for a 3-year window). Default is NULL (no smoothing).

Value

A list with the following components:

data

Tibble with CCT data containing columns: group, year, index

plots

Named list of plotly objects showing temporal evolution of CCT for each group. Each plot shows both absolute CCT values and year-over-year differences.

years_range

Named vector with start_year and end_year used in the analysis

tracked_cr_py

Citation year data with columns CR and CR_PY. Can be saved and reused in subsequent analyses to avoid repeated API calls.

Details

The Citation Cycle Time (CCT) is calculated following Kayal (1999):

  1. Extract citation IDs from the network's CR column

  2. Fetch publication years for cited works from OpenAlex API using get_openalex_fields()

  3. For each publication, calculate the age of each cited reference (PY - CR_PY)

  4. Calculate the median citation age per publication

  5. For each year, calculate the median of per-publication medians across all publications in that year (annual mode)

Lower CCT values indicate that publications are citing more recent work, suggesting a faster pace of knowledge replacement. A sudden drop in CCT within a group signals potential scientific emergence.

The function automatically handles:

  • Splitting semicolon-separated citation IDs

  • Batch processing of OpenAlex API requests

  • Filtering invalid citations (where cited work was published after citing work)

  • Skipping years with too few papers (min_papers_per_year)

  • Optional rolling window smoothing for noisy time series

  • Creating temporal plots for each group

References

Kayal AA, Waters RC. An empirical evaluation of the technology cycle time indicator as a measure of the pace of technological progress in superconductor technology. IEEE Transactions on Engineering Management. 1999;46(2):127-31. doi:10.1109/17.759138

Examples

if (FALSE) { # \dontrun{
# Group analysis
results <- sniff_citations_cycle_time(network_groups, scope = "groups")

# Network analysis
results_network <- sniff_citations_cycle_time(complete_network, scope = "network")

# With rolling window smoothing
results_smooth <- sniff_citations_cycle_time(
  network_groups,
  scope = "groups",
  rolling_window = 3
)

# Accessing results
cct_data <- results$data
plots <- results$plots
plots$c1g1  # View plot for specific group

# Reuse citation data to avoid repeated API calls
saved_citations <- results$tracked_cr_py
results2 <- sniff_citations_cycle_time(
  network_groups,
  tracked_cr_py = saved_citations
)
} # }