Zum Erstellen des gewünschten genau verschachtelten Objekts verwenden wir eine Mischung aus reinem JavaScript und einer D3-Methode mit dem Namen d3.stratify
. Beachten Sie jedoch, dass 7 Millionen Zeilen (siehe Post-Scriptum unten) viel zu berechnen sind.
Es ist sehr wichtig zu erwähnen, dass Sie für diese vorgeschlagene Lösung die Königreiche in verschiedene Datenfelder trennen müssen (z. B. mithilfe von Array.prototype.filter
). Diese Einschränkung tritt auf, weil wir einen Wurzelknoten benötigen und in der linnäischen Taxonomie keine Beziehung zwischen Königreichen besteht (es sei denn, Sie erstellen "Domäne" als obersten Rang, der die Wurzel für alle Eukaryoten ist, aber dann haben Sie dieselbe Problem für Archaea und Bakterien).
Angenommen, Sie haben diese CSV (ich habe einige weitere Zeilen hinzugefügt) mit nur einem Königreich:
RecordID,kingdom,phylum,class,order,family,genus,species
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Homo,Homo sapiens
2,Animalia,Chordata,Mammalia,Carnivora,Canidae,Canis,Canis latrans
3,Animalia,Chordata,Mammalia,Cetacea,Delphinidae,Tursiops,Tursiops truncatus
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Pan,Pan paniscus
Basierend auf dieser CSV erstellen wir hier ein Array mit dem Namen, tableOfRelationships
das, wie der Name schon sagt, die Beziehungen zwischen den Rängen aufweist:
const data = d3.csvParse(csv);
const taxonomicRanks = data.columns.filter(d => d !== "RecordID");
const tableOfRelationships = [];
data.forEach(row => {
taxonomicRanks.forEach((d, i) => {
if (!tableOfRelationships.find(e => e.name === row[d])) tableOfRelationships.push({
name: row[d],
parent: row[taxonomicRanks[i - 1]] || null
})
})
});
Für die obigen Daten ist dies tableOfRelationships
:
+---------+----------------------+---------------+
| (Index) | name | parent |
+---------+----------------------+---------------+
| 0 | "Animalia" | null |
| 1 | "Chordata" | "Animalia" |
| 2 | "Mammalia" | "Chordata" |
| 3 | "Primates" | "Mammalia" |
| 4 | "Hominidae" | "Primates" |
| 5 | "Homo" | "Hominidae" |
| 6 | "Homo sapiens" | "Homo" |
| 7 | "Carnivora" | "Mammalia" |
| 8 | "Canidae" | "Carnivora" |
| 9 | "Canis" | "Canidae" |
| 10 | "Canis latrans" | "Canis" |
| 11 | "Cetacea" | "Mammalia" |
| 12 | "Delphinidae" | "Cetacea" |
| 13 | "Tursiops" | "Delphinidae" |
| 14 | "Tursiops truncatus" | "Tursiops" |
| 15 | "Pan" | "Hominidae" |
| 16 | "Pan paniscus" | "Pan" |
+---------+----------------------+---------------+
Schauen Sie sich null
als übergeordnetes Element Folgendes an Animalia
: Deshalb habe ich Ihnen gesagt, dass Sie Ihren Datensatz nach Königreichen trennen müssen. Es kann nur einen null
Wert in der gesamten Tabelle geben.
Basierend auf dieser Tabelle erstellen wir schließlich die Hierarchie mit d3.stratify()
:
const stratify = d3.stratify()
.id(function(d) { return d.name; })
.parentId(function(d) { return d.parent; });
const hierarchicalData = stratify(tableOfRelationships);
Und hier ist die Demo. Öffnen Sie die Konsole Ihres Browsers (die des Snippets ist für diese Aufgabe nicht sehr gut geeignet) und überprüfen Sie die verschiedenen Ebenen ( children
) des Objekts:
const csv = `RecordID,kingdom,phylum,class,order,family,genus,species
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Homo,Homo sapiens
2,Animalia,Chordata,Mammalia,Carnivora,Canidae,Canis,Canis latrans
3,Animalia,Chordata,Mammalia,Cetacea,Delphinidae,Tursiops,Tursiops truncatus
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Pan,Pan paniscus`;
const data = d3.csvParse(csv);
const taxonomicRanks = data.columns.filter(d => d !== "RecordID");
const tableOfRelationships = [];
data.forEach(row => {
taxonomicRanks.forEach((d, i) => {
if (!tableOfRelationships.find(e => e.name === row[d])) tableOfRelationships.push({
name: row[d],
parent: row[taxonomicRanks[i - 1]] || null
})
})
});
const stratify = d3.stratify()
.id(function(d) {
return d.name;
})
.parentId(function(d) {
return d.parent;
});
const hierarchicalData = stratify(tableOfRelationships);
console.log(hierarchicalData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
PS : Ich weiß nicht, welche Art von Daten Sie erstellen werden, aber Sie sollten taxonomische Ränge wirklich vermeiden. Die gesamte linnäische Taxonomie ist veraltet, wir verwenden keine Ränge mehr: Da die phylogenetische Systematik Mitte der 60er Jahre entwickelt wurde, verwenden wir nur Taxa ohne taxonomischen Rang (Lehrer für Evolutionsbiologie hier). Ich bin auch ziemlich neugierig auf diese 7 Millionen Reihen, da wir etwas mehr als 1 Million Arten beschrieben haben!
nan
für das Phylum enthaltende Magnoliopsida. Was ist dasnan
? Das Phylum ist Anthophyta oder alternativ Magnolie (es ist das alte Phylum Angiospermae).