Для створення точного вкладеного об'єкта, який ви хочете, ми будемо використовувати суміш чистого JavaScript та метод D3 з назвою d3.stratify
. Однак майте на увазі, що 7 мільйонів рядків (див. Пост scriptum нижче) - це багато для обчислення.
Дуже важливо згадати, що для цього запропонованого рішення вам доведеться відокремлювати Королівства в різних масивах даних (наприклад, використовуючи Array.prototype.filter
). Це обмеження виникає тому, що нам потрібен кореневий вузол, і в лінійській систематиці немає відносин між Королівствами (якщо ви не створите "Домен" як вищий ранг, який буде коренем для всіх еукаріотів, але тоді у вас буде те саме проблема для Археї та бактерій).
Отже, припустимо, у вас є цей 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
На основі цього CSV ми створимо тут масив з назвою, tableOfRelationships
який, як випливає з назви, має зв'язки між рядами:
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
})
})
});
Для наведених вище даних це 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" |
+---------+----------------------+---------------+
Подивіться на null
батьків як Animalia
: тому я сказав вам, що вам потрібно відокремити свій набір даних від Kingdoms, null
у всій таблиці може бути лише одне значення.
Нарешті, на основі цієї таблиці ми створюємо ієрархію, використовуючи d3.stratify()
:
const stratify = d3.stratify()
.id(function(d) { return d.name; })
.parentId(function(d) { return d.parent; });
const hierarchicalData = stratify(tableOfRelationships);
І ось демонстрація. Відкрийте консоль веб-переглядача (фрагмент фрагмента не дуже хороший для цього завдання) і перевірте кілька рівнів ( children
) об'єкта:
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 : Я не знаю, який тип даних ви створите, але вам справді слід уникати таксономічних рангів. Вся лінійська систематика застаріла, ми вже не використовуємо ранги: оскільки філогенетична систематика була розроблена в середині 60-х, ми використовуємо лише таксони, без будь-якого таксономічного рангу (тут еволюційний викладач біології). Також мені досить цікаво про ці 7 мільйонів рядків, оскільки ми описали трохи більше 1 мільйона видів!
nan
типи, що містять Magnoliopsida. Що цеnan
? Характер - це Anthophyta, або, магнолія, старий Phylum Angiospermae.