logo Netzschleuder network catalog, repository, and centrifuge

History of sp_kenyan_households

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] Fix parse bugs and improve descriptions and metadata by Tiago de Paula Peixoto 6bb6851
- parse fixes from the review of the descriptions, e.g. us_patents
  (directed), celegans_2019 (synapse direction), ecoli_transcription and
  yeast_transcription (regulator to target), bitcoin (direction, phantom
  node), ego_social (Google+ features and circles), scotus_majority,
  arxiv_authors and social_location (as in SNAP), caida_as, dnc, dom,
  mist, reuters and bibsonomy (names on the right nodes), uci_zoo
- every description now states explicitly what the nodes and edges
  represent; corrected titles, years, tags, citations and licences
- the "Hypergraph" tag is removed; very large entries are marked
  `huge = True` (see --skip-huge)
- ICON ids of partial duplicates added (hiv_transmission, congress_bills,
  openflights, dutch_school)
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
index 39e3a6a..67878a1 100644
--- a/entries/sp_kenyan_households/__init__.py
+++ b/entries/sp_kenyan_households/__init__.py
@@ -19,35 +19,24 @@
 from .. import *
 
 title = "Kenyan households contacts (2012)"
-description = """A network of proximity contacts measured between members of 5 households of rural Kenya, between April 24 and May 12, 2012.[^icon]
+description = """Network of face-to-face proximity contacts among members of 5 households in rural Kenya (in the Kilifi Health and Demographic Surveillance System area), measured with wearable proximity sensors between 24 April and 12 May 2012 as part of a SocioPatterns study. The members of each household wore the sensors for three consecutive days. Nodes are household members and each edge is a contact event between two members, either of the same household or of different households, recorded during the daytime (between 7:00 and 20:00). Two members can be connected by multiple edges, one per contact event.
 
-Each file in the downloadable package contains a comma-separated list representing each measured contact between any two household members (member 1 and member 2) over three days of experiment. The first file stores the contacts recorded between members of the same household, the second file stores the contacts between members of different households.
+The network has the following properties:
 
-Each line has the form: “h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day, hour”, where:
-
-```
-    h1 is the household of member 1; h1=[L, F, E, B, H]
-    m1 is the anonymous ID number of member 1;
-    h2 is the household of member 2; h2=[L, F, E, B, H]
-    m2 is the anonymous ID number of member 2;
-    age1 is the age of member 1; age1 = [0, 1, 2, 3, 4]
-    age2 is the age of member 2; age2 = [0, 1, 2, 3, 4]
-    sex1 is the gender of member 1; sex1 = [F, M]
-    sex2 is the gender of member 2; sex2 = [F, M]
-    duration is the duration of the contact event in seconds;
-    day is the day of experiment; day = [1, 2, 3]
-    hour is the day time of the contact event; hour = [7 – 20]
-```
-
-[^icon]: Description obtained from the [ICON](https://icon.colorado.edu) project.
-"""
+- `id`: the anonymous identifier of the member, unique only within its household (members are identified by the pair `house`, `id`).
+- `house`: the household of the member (`L`, `F`, `E`, `B` or `H`).
+- `age`: the age category of the member, coded from 0 to 4 (see Kiti et al. for the definition of the categories).
+- `sex`: the sex of the member (`F` or `M`).
+- `duration`: the duration of the contact event in seconds.
+- `day`: the day of the experiment in which the contact took place (1, 2 or 3).
+- `hour`: the hour of the day in which the contact took place (7 to 20)."""
 tags = ['Social', 'Offline', 'Unweighted', 'Temporal', 'Metadata']
-url = 'http://www.sociopatterns.org/datasets/kenyan-households-contact-network/'
+url = 'https://sociopatterns.org/datasets/kenyan-households-contact-network/'
 citation = [('M. Kiti et al., "Quantifying social contacts in a household setting of rural Kenya using wearable proximity sensors." EPJ Data Science 5, 21 (2016)', 'https://doi.org/10.1140/epjds/s13688-016-0084-2')]
 icon_hash = '594b41a04ed8f1bb6022ae47'
-ustream_license = ("Creative Commons Attribution-NonCommercial-ShareAlike",
-                   "http://creativecommons.org/licenses/by-nc-sa/3.0/")
-upstream_prefix = 'http://www.sociopatterns.org/wp-content/uploads/2016/06'
+upstream_license = ("Creative Commons CC0 1.0 Universal (Public Domain Dedication)",
+                    "https://creativecommons.org/publicdomain/zero/1.0/")
+upstream_prefix = 'https://sociopatterns.org/assets/data'
 files = [(('scc2034_household_contact_dataset.zip:scc2034_kilifi_all_contacts_within_households.csv',
            'scc2034_household_contact_dataset.zip:scc2034_kilifi_all_contacts_across_households.csv'), None, None)]
 
@@ -70,23 +59,27 @@ def parse(alts=None):
             fs = [stack.enter_context(open_upstream_file(name, fn, "r")) for fn in fnames]
 
             g = Graph(directed=False)
-            g.ep.duration = g.new_ep("string")
-            g.ep.day = g.new_ep("string")
-            g.ep.hour = g.new_ep("string")
+            # members are identified by the pair (household, member id), since
+            # member ids are unique only within each household
             def get_edges():
                 for f in fs:
                     reader = csv.reader(f, delimiter=",")
                     next(reader)
                     for rows in reader:
                         h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day, hour = rows
-                        yield m1, m2, duration, day, hour
-            g.vp.id = g.add_edge_list(get_edges(), hashed=True,
-                                      hash_type="string",
-                                      eprops=[g.ep.duration, g.ep.day, g.ep.hour])
-            vs = {g.vp.id[v] : v for v in g.vertices()}
+                        yield (f"{h1}:{m1}", f"{h2}:{m2}", int(duration),
+                               int(day), int(hour))
+            g.ep.duration = g.new_ep("int")
+            g.ep.day = g.new_ep("int")
+            g.ep.hour = g.new_ep("int")
+            key = g.add_edge_list(get_edges(), hashed=True,
+                                  hash_type="string",
+                                  eprops=[g.ep.duration, g.ep.day, g.ep.hour])
+            vs = {key[v] : v for v in g.vertices()}
 
+            g.vp.id = g.new_vp("int")
             g.vp.house = g.new_vp("string")
-            g.vp.age = g.new_vp("string")
+            g.vp.age = g.new_vp("int")
             g.vp.sex = g.new_vp("string")
             for f in fs:
                 f.seek(0)
@@ -94,15 +87,19 @@ def parse(alts=None):
                 next(reader)
                 for rows in reader:
                     h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day, hour = rows
-                    s = vs[m1]
-                    g.vp.house[s] = h1
-                    g.vp.age[s] = age1
-                    g.vp.sex[s] = sex1
-                    t = vs[m2]
-                    g.vp.house[t] = h2
-                    g.vp.age[t] = age2
-                    g.vp.sex[t] = sex2
+                    for h, m, age, sex in [(h1, m1, age1, sex1),
+                                           (h2, m2, age2, sex2)]:
+                        v = vs[f"{h}:{m}"]
+                        g.vp.id[v] = int(m)
+                        g.vp.house[v] = h
+                        g.vp.age[v] = int(age)
+                        g.vp.sex[v] = sex
 
-            g = Graph(g, vorder=g.vp.id)
+            order = g.new_vp("int")
+            for i, v in enumerate(sorted(g.vertices(),
+                                         key=lambda v: (g.vp.house[v],
+                                                        g.vp.id[v]))):
+                order[v] = i
+            g = Graph(g, vorder=order)
 
         yield alt, g
Update copyright information by Tiago de Paula Peixoto 73a4f0d
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
index 73ac551..39e3a6a 100644
--- a/entries/sp_kenyan_households/__init__.py
+++ b/entries/sp_kenyan_households/__init__.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2020-2024 Tiago de Paula Peixoto <tiago@skewed.de>
+# Copyright (C) 2020-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
Update copyright information by Tiago de Paula Peixoto 3d288ea
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
index d543412..73ac551 100644
--- a/entries/sp_kenyan_households/__init__.py
+++ b/entries/sp_kenyan_households/__init__.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2020-2023 Tiago de Paula Peixoto <tiago@skewed.de>
+# Copyright (C) 2020-2024 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
Update copyright information by Tiago de Paula Peixoto 8d005ae
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
index 2eff0bb..d543412 100644
--- a/entries/sp_kenyan_households/__init__.py
+++ b/entries/sp_kenyan_households/__init__.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2021 Tiago de Paula Peixoto <tiago@skewed.de>
+# Copyright (C) 2020-2023 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
Update copyright info by Tiago de Paula Peixoto db2efcc
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
index ae65e7f..2eff0bb 100644
--- a/entries/sp_kenyan_households/__init__.py
+++ b/entries/sp_kenyan_households/__init__.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2020 Tiago de Paula Peixoto <tiago@skewed.de>
+# Copyright (C) 2021 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
Update citations to use DOIs by Tiago de Paula Peixoto e878874
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
index 7d30bc1..ae65e7f 100644
--- a/entries/sp_kenyan_households/__init__.py
+++ b/entries/sp_kenyan_households/__init__.py
@@ -43,7 +43,7 @@ Each line has the form: “h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day
 """
 tags = ['Social', 'Offline', 'Unweighted', 'Temporal', 'Metadata']
 url = 'http://www.sociopatterns.org/datasets/kenyan-households-contact-network/'
-citation = [('M. Kiti et al., "Quantifying social contacts in a household setting of rural Kenya using wearable proximity sensors." EPJ Data Science 5, 21 (2016)', 'https://epjdatascience.springeropen.com/articles/10.1140/epjds/s13688-016-0084-2')]
+citation = [('M. Kiti et al., "Quantifying social contacts in a household setting of rural Kenya using wearable proximity sensors." EPJ Data Science 5, 21 (2016)', 'https://doi.org/10.1140/epjds/s13688-016-0084-2')]
 icon_hash = '594b41a04ed8f1bb6022ae47'
 ustream_license = ("Creative Commons Attribution-NonCommercial-ShareAlike",
                    "http://creativecommons.org/licenses/by-nc-sa/3.0/")
Change license from GPLv3 to AGPLv3 by Tiago de Paula Peixoto d754be5
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
index 6db2d0f..7d30bc1 100644
--- a/entries/sp_kenyan_households/__init__.py
+++ b/entries/sp_kenyan_households/__init__.py
@@ -3,18 +3,18 @@
 #
 # Copyright (C) 2020 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 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 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 General Public License for more details.
+# 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 General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# 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 *
 
Add explicit attribution to descriptions obtained from ICON by Tiago de Paula Peixoto 1645314
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
index 0eb7f76..6db2d0f 100644
--- a/entries/sp_kenyan_households/__init__.py
+++ b/entries/sp_kenyan_households/__init__.py
@@ -19,12 +19,13 @@
 from .. import *
 
 title = "Kenyan households contacts (2012)"
-description = """A network of proximity contacts measured between members of 5 households of rural Kenya, between April 24 and May 12, 2012.
+description = """A network of proximity contacts measured between members of 5 households of rural Kenya, between April 24 and May 12, 2012.[^icon]
 
 Each file in the downloadable package contains a comma-separated list representing each measured contact between any two household members (member 1 and member 2) over three days of experiment. The first file stores the contacts recorded between members of the same household, the second file stores the contacts between members of different households.
 
 Each line has the form: “h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day, hour”, where:
 
+```
     h1 is the household of member 1; h1=[L, F, E, B, H]
     m1 is the anonymous ID number of member 1;
     h2 is the household of member 2; h2=[L, F, E, B, H]
@@ -36,7 +37,9 @@ Each line has the form: “h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day
     duration is the duration of the contact event in seconds;
     day is the day of experiment; day = [1, 2, 3]
     hour is the day time of the contact event; hour = [7 – 20]
+```
 
+[^icon]: Description obtained from the [ICON](https://icon.colorado.edu) project.
 """
 tags = ['Social', 'Offline', 'Unweighted', 'Temporal', 'Metadata']
 url = 'http://www.sociopatterns.org/datasets/kenyan-households-contact-network/'
Initial commit by Tiago de Paula Peixoto cc85872
diff --git a/entries/sp_kenyan_households/__init__.py b/entries/sp_kenyan_households/__init__.py
new file mode 100644
index 0000000..0eb7f76
--- /dev/null
+++ b/entries/sp_kenyan_households/__init__.py
@@ -0,0 +1,105 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2020 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 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from .. import *
+
+title = "Kenyan households contacts (2012)"
+description = """A network of proximity contacts measured between members of 5 households of rural Kenya, between April 24 and May 12, 2012.
+
+Each file in the downloadable package contains a comma-separated list representing each measured contact between any two household members (member 1 and member 2) over three days of experiment. The first file stores the contacts recorded between members of the same household, the second file stores the contacts between members of different households.
+
+Each line has the form: “h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day, hour”, where:
+
+    h1 is the household of member 1; h1=[L, F, E, B, H]
+    m1 is the anonymous ID number of member 1;
+    h2 is the household of member 2; h2=[L, F, E, B, H]
+    m2 is the anonymous ID number of member 2;
+    age1 is the age of member 1; age1 = [0, 1, 2, 3, 4]
+    age2 is the age of member 2; age2 = [0, 1, 2, 3, 4]
+    sex1 is the gender of member 1; sex1 = [F, M]
+    sex2 is the gender of member 2; sex2 = [F, M]
+    duration is the duration of the contact event in seconds;
+    day is the day of experiment; day = [1, 2, 3]
+    hour is the day time of the contact event; hour = [7 – 20]
+
+"""
+tags = ['Social', 'Offline', 'Unweighted', 'Temporal', 'Metadata']
+url = 'http://www.sociopatterns.org/datasets/kenyan-households-contact-network/'
+citation = [('M. Kiti et al., "Quantifying social contacts in a household setting of rural Kenya using wearable proximity sensors." EPJ Data Science 5, 21 (2016)', 'https://epjdatascience.springeropen.com/articles/10.1140/epjds/s13688-016-0084-2')]
+icon_hash = '594b41a04ed8f1bb6022ae47'
+ustream_license = ("Creative Commons Attribution-NonCommercial-ShareAlike",
+                   "http://creativecommons.org/licenses/by-nc-sa/3.0/")
+upstream_prefix = 'http://www.sociopatterns.org/wp-content/uploads/2016/06'
+files = [(('scc2034_household_contact_dataset.zip:scc2034_kilifi_all_contacts_within_households.csv',
+           'scc2034_household_contact_dataset.zip:scc2034_kilifi_all_contacts_across_households.csv'), None, None)]
+
+def fetch_upstream(force=False):
+    return fetch_upstream_files(__name__.split(".")[-1], upstream_prefix, files,
+                                force)
+
+@cache_network()
+@coerce_props()
+@annotate()
+def parse(alts=None):
+    global files
+    name = __name__.split(".")[-1]
+    for fnames, alt, fmt in files:
+        if alts is not None and alt not in alts:
+            continue
+        if isinstance(fnames, str):
+            fnames = [fnames]
+        with ExitStack() as stack:
+            fs = [stack.enter_context(open_upstream_file(name, fn, "r")) for fn in fnames]
+
+            g = Graph(directed=False)
+            g.ep.duration = g.new_ep("string")
+            g.ep.day = g.new_ep("string")
+            g.ep.hour = g.new_ep("string")
+            def get_edges():
+                for f in fs:
+                    reader = csv.reader(f, delimiter=",")
+                    next(reader)
+                    for rows in reader:
+                        h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day, hour = rows
+                        yield m1, m2, duration, day, hour
+            g.vp.id = g.add_edge_list(get_edges(), hashed=True,
+                                      hash_type="string",
+                                      eprops=[g.ep.duration, g.ep.day, g.ep.hour])
+            vs = {g.vp.id[v] : v for v in g.vertices()}
+
+            g.vp.house = g.new_vp("string")
+            g.vp.age = g.new_vp("string")
+            g.vp.sex = g.new_vp("string")
+            for f in fs:
+                f.seek(0)
+                reader = csv.reader(f, delimiter=",")
+                next(reader)
+                for rows in reader:
+                    h1, m1, h2, m2, age1, age2, sex1, sex2, duration, day, hour = rows
+                    s = vs[m1]
+                    g.vp.house[s] = h1
+                    g.vp.age[s] = age1
+                    g.vp.sex[s] = sex1
+                    t = vs[m2]
+                    g.vp.house[t] = h2
+                    g.vp.age[t] = age2
+                    g.vp.sex[t] = sex2
+
+            g = Graph(g, vorder=g.vp.id)
+
+        yield alt, g