logo Netzschleuder network catalog, repository, and centrifuge

History of cjeu_citations

The changes to the source code of this entry in the repository, newest first, each with the differences it made to the entry's files. They are also listed on GitLab.

[entries] Add the date when each entry was added, and remove icon_hash by Tiago de Paula Peixoto beff7c9
The dates are those of the commits that first added the entries' files
(2020-08-11 for the entries of the initial commit); renamed entries keep
the date of their first name.

Changed: none
diff --git a/entries/cjeu_citations/__init__.py b/entries/cjeu_citations/__init__.py
index 112c4d7..389bd78 100644
--- a/entries/cjeu_citations/__init__.py
+++ b/entries/cjeu_citations/__init__.py
@@ -47,7 +47,7 @@ citation = [('K. Moodley, P. V. Hernandez Serrano, G. van Dijck, M. Dumontier, "
              'https://doi.org/10.3233/FAIA190307'),
             ('K. Moodley, P. Hernandez-Serrano, "Court of Justice of the EU case citations and full texts." Zenodo (2020)',
              'https://doi.org/10.5281/zenodo.3912042')]
-icon_hash = None
+date_added = '2026-10-31'
 upstream_license = ("GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)",
                     "https://www.gnu.org/licenses/agpl-3.0.en.html")
 
[entries] Prefix the properties in the descriptions with (Node), (Edge) or (Graph) by Tiago de Paula Peixoto bc3dbbd
The lists of properties at the end of the descriptions marked edge
properties with "Edge" but left node properties unmarked, or grouped
them in "Nodes: `a`, ...; `b`, ..." items, so the kind of a property
was often unclear. Every item now starts with (Node), (Edge) or (Graph),
followed by the property names, a colon and the explanation, one item
per property or group of properties; qualifications (kinds of nodes,
networks) follow the names in parentheses. Properties that were only
named got a short explanation, and a few items that named the wrong
kind of property were corrected.
diff --git a/entries/cjeu_citations/__init__.py b/entries/cjeu_citations/__init__.py
index 52c029e..112c4d7 100644
--- a/entries/cjeu_citations/__init__.py
+++ b/entries/cjeu_citations/__init__.py
@@ -29,18 +29,18 @@ The data were released in two versions on Zenodo, with the same citations: the f
 
 The network has the following properties:
 
-- `celex`: the CELEX number of the decision (the document identifier of EUR-Lex).
-- `has_metadata`: whether the decision has metadata in the dataset.
-- `case_label`: the case number (e.g. `Case C-32/95 P`, `Joined cases C-147/97 and C-148/97`).
-- `ecli`: the European Case Law Identifier (e.g. `EU:C:2000:74`).
-- `case_type`: `Judgement` or `Order` (empty if not specified).
-- `judge`: the judge-rapporteur; `advocate`: the advocate general.
-- `country`: the country of origin of the case (e.g. of the court that asked for a preliminary ruling).
-- `chamber`: the formation of the Court (e.g. `Sixth Chamber`; empty if not specified).
-- `lodge_date`, `document_date`: the dates on which the case was lodged and the decision was issued (`YYYY-MM-DD`).
-- `joined_cases`: the number of joined cases decided.
-- `ruling_title`, `ruling_name`, `ruling_type`, `ruling_content`: the title of the decision, the names of the parties, the type of proceedings (e.g. reference for a preliminary ruling by a given court), and the keywords of its subject matter.
-- `topics`: the subject matters of the decision in EUR-Lex (e.g. `Free movement of goods`, `Competition`)."""
+- (Node) `celex`: the CELEX number of the decision (the document identifier of EUR-Lex).
+- (Node) `has_metadata`: whether the decision has metadata in the dataset.
+- (Node) `case_label`: the case number (e.g. `Case C-32/95 P`, `Joined cases C-147/97 and C-148/97`).
+- (Node) `ecli`: the European Case Law Identifier (e.g. `EU:C:2000:74`).
+- (Node) `case_type`: `Judgement` or `Order` (empty if not specified).
+- (Node) `judge`: the judge-rapporteur; `advocate`: the advocate general.
+- (Node) `country`: the country of origin of the case (e.g. of the court that asked for a preliminary ruling).
+- (Node) `chamber`: the formation of the Court (e.g. `Sixth Chamber`; empty if not specified).
+- (Node) `lodge_date`, `document_date`: the dates on which the case was lodged and the decision was issued (`YYYY-MM-DD`).
+- (Node) `joined_cases`: the number of joined cases decided.
+- (Node) `ruling_title`, `ruling_name`, `ruling_type`, `ruling_content`: the title of the decision, the names of the parties, the type of proceedings (e.g. reference for a preliminary ruling by a given court), and the keywords of its subject matter.
+- (Node) `topics`: the subject matters of the decision in EUR-Lex (e.g. `Free movement of goods`, `Competition`)."""
 tags = ['Informational', 'Citation', 'Legal', 'Unweighted', 'Metadata']
 url = ['https://doi.org/10.5281/zenodo.3912042', 'https://doi.org/10.5281/zenodo.3926736']
 citation = [('K. Moodley, P. V. Hernandez Serrano, G. van Dijck, M. Dumontier, "Similarity and Relevance of Court Decisions: A Computational Study on CJEU Cases." Legal Knowledge and Information Systems (JURIX 2019), Frontiers in Artificial Intelligence and Applications (2019)',
[entries] New entry: cjeu_citations by Tiago de Paula Peixoto 47cf656
diff --git a/entries/cjeu_citations/__init__.py b/entries/cjeu_citations/__init__.py
new file mode 100644
index 0000000..52c029e
--- /dev/null
+++ b/entries/cjeu_citations/__init__.py
@@ -0,0 +1,115 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2026 Tiago de Paula Peixoto <tiago@skewed.de>
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+from .. import *
+import pandas
+
+title = "Court of Justice of the EU case citations (1954-2018)"
+description = r"""A directed network of citations between the decisions (judgments and orders) of the Court of Justice of the European Union (CJEU), compiled by K. Moodley and P. Hernandez-Serrano (Institute of Data Science, Maastricht University) from the decisions published on EUR-Lex, the portal of EU law, until December 2018, for a study of the similarity and relevance of court decisions.
+
+Each node is a decision, identified by its CELEX number (e.g. `61997CJ0147`), and a directed edge from A to B means that decision A cites decision B (as recorded by EUR-Lex). The nodes are the 13,780 decisions with metadata in the dataset, and the 543 cited decisions without metadata (which have empty attributes). A few decisions (82) cite themselves (self-loops).
+
+The data were released in two versions on Zenodo, with the same citations: the first (used here) also contains the metadata and the subject topics of the decisions, which the second leaves out. The full texts of the decisions (also in the dataset) are not included, and neither are the columns of the metadata derived from the others (year and month of the dates, duration of the case, number of countries, country and chamber combined, and the number of main subjects).
+
+The network has the following properties:
+
+- `celex`: the CELEX number of the decision (the document identifier of EUR-Lex).
+- `has_metadata`: whether the decision has metadata in the dataset.
+- `case_label`: the case number (e.g. `Case C-32/95 P`, `Joined cases C-147/97 and C-148/97`).
+- `ecli`: the European Case Law Identifier (e.g. `EU:C:2000:74`).
+- `case_type`: `Judgement` or `Order` (empty if not specified).
+- `judge`: the judge-rapporteur; `advocate`: the advocate general.
+- `country`: the country of origin of the case (e.g. of the court that asked for a preliminary ruling).
+- `chamber`: the formation of the Court (e.g. `Sixth Chamber`; empty if not specified).
+- `lodge_date`, `document_date`: the dates on which the case was lodged and the decision was issued (`YYYY-MM-DD`).
+- `joined_cases`: the number of joined cases decided.
+- `ruling_title`, `ruling_name`, `ruling_type`, `ruling_content`: the title of the decision, the names of the parties, the type of proceedings (e.g. reference for a preliminary ruling by a given court), and the keywords of its subject matter.
+- `topics`: the subject matters of the decision in EUR-Lex (e.g. `Free movement of goods`, `Competition`)."""
+tags = ['Informational', 'Citation', 'Legal', 'Unweighted', 'Metadata']
+url = ['https://doi.org/10.5281/zenodo.3912042', 'https://doi.org/10.5281/zenodo.3926736']
+citation = [('K. Moodley, P. V. Hernandez Serrano, G. van Dijck, M. Dumontier, "Similarity and Relevance of Court Decisions: A Computational Study on CJEU Cases." Legal Knowledge and Information Systems (JURIX 2019), Frontiers in Artificial Intelligence and Applications (2019)',
+             'https://doi.org/10.3233/FAIA190307'),
+            ('K. Moodley, P. Hernandez-Serrano, "Court of Justice of the EU case citations and full texts." Zenodo (2020)',
+             'https://doi.org/10.5281/zenodo.3912042')]
+icon_hash = None
+upstream_license = ("GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)",
+                    "https://www.gnu.org/licenses/agpl-3.0.en.html")
+
+# The first version of the record (the second, 10.5281/zenodo.3926736, under
+# CC BY 2.0, has the same citations.csv, but no metadata.csv or topics.csv)
+upstream_prefix = 'https://zenodo.org/records/3912042/files'
+files = [(("cjeudataset_dec2018.zip:citations.csv",
+           "cjeudataset_dec2018.zip:metadata.csv",
+           "cjeudataset_dec2018.zip:topics.csv"), None, None)]
+
+def fetch_upstream(force=False):
+    return fetch_upstream_files(__name__.split(".")[-1], upstream_prefix, files,
+                                force)
+
+_str_cols = {"case_label": "case_label", "ecli": "ecli",
+             "case_type": "case_type", "judge": "judge",
+             "advocate": "advocate", "country": "country",
+             "chamber": "chamber", "lodge_date": "lodge_date",
+             "document_date": "document_date",
+             "ruling_title": "ruling_title", "ruling_name": "ruling_name",
+             "ruling_type": "ruling_type", "ruling_content": "ruling_content"}
+
+# For checks only: if set, only this many rows are read of each file
+_check_rows = None
+
+@cache_network()
+@coerce_props()
+@annotate()
+def parse(alts=None):
+    name = __name__.split(".")[-1]
+    for fnames, alt, fmt in files:
+        if alts is not None and alt not in alts:
+            continue
+        tabs = []
+        for fn in fnames:
+            with open_upstream_file(name, fn, "rb") as f:
+                tabs.append(pandas.read_csv(f, dtype=str, keep_default_na=False,
+                                             nrows=_check_rows))
+        cit, meta, topics = tabs
+        celex = list(meta["source"])
+        idx = {c: i for i, c in enumerate(celex)}
+        for c in pandas.concat([cit["source"], cit["target"]]):
+            if c not in idx:
+                idx[c] = len(idx)
+                celex.append(c)
+        n_meta = len(meta)
+        g = Graph(directed=True)
+        g.add_vertex(len(idx))
+        g.add_edge_list([(idx[s], idx[t]) for s, t in zip(cit["source"], cit["target"])])
+        g.vp.celex = g.new_vp("string", vals=celex)
+        g.vp.has_metadata = g.new_vp("bool", vals=[i < n_meta for i in range(len(idx))])
+        pad = [""] * (len(idx) - n_meta)
+        for c, k in _str_cols.items():
+            vals = [" ".join(x.split()) for x in meta[c]]
+            vals = ["" if x in ("not_specified", "blank_subject") else x
+                    for x in vals]
+            g.vp[k] = g.new_vp("string", vals=vals + pad)
+        jc = [int(float(x)) if x not in ("", "not_specified") else -1
+              for x in meta["joined_cases"]]
+        g.vp.joined_cases = g.new_vp("int", vals=jc + [-1] * len(pad))
+        top = defaultdict(list)
+        for s, t in zip(topics["source"], topics["topic"]):
+            top[s].append(t)
+        g.vp.topics = g.new_vp("vector<string>", vals=[top.get(c, []) for c in celex])
+        yield alt, g