Tam olarak istediğiniz iç içe geçmiş nesneyi oluşturmak için saf JavaScript ve adlandırılmış bir D3 yöntemi karışımı kullanacağız d3.stratify
. Ancak, 7 milyon satırın (lütfen aşağıdaki yazı komut dosyasına bakın) hesaplanması gereken çok şey olduğunu unutmayın.
Önerilen bu çözüm için, Krallıkları farklı veri dizilerinde (örneğin, kullanarak Array.prototype.filter
) ayırmanız gerekeceğinden bahsetmek çok önemlidir . Bu kısıtlama, bir kök düğüme ihtiyacımız olduğu için gerçekleşir ve Linna taksonomisinde Krallıklar arasında bir ilişki yoktur ( tüm ökaryotların kökü olacak bir üst sıra olarak "Etki Alanı" oluşturmazsanız , ancak aynı Archaea ve Bakteriler için problem).
Diyelim ki sadece bir Krallık ile bu CSV'ye (birkaç satır daha ekledim) sahipsin:
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
Bu CSV'ye dayanarak, burada tableOfRelationships
adından da anlaşılacağı gibi, dereceler arasında ilişkileri olan bir dizi oluşturacağız :
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
})
})
});
Yukarıdaki veriler için bu 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" |
+---------+----------------------+---------------+
Şunun null
ebeveyni olarak bakın Animalia
: bu yüzden veri setinizi Krallıklar ile ayırmanız gerektiğini söyledim null
, tüm tabloda sadece bir değer olabilir .
Son olarak, bu tabloya dayanarak, hiyerarşiyi aşağıdakileri kullanarak oluştururuz d3.stratify()
:
const stratify = d3.stratify()
.id(function(d) { return d.name; })
.parentId(function(d) { return d.parent; });
const hierarchicalData = stratify(tableOfRelationships);
Ve işte demo. Tarayıcınızın konsolunu açın (snippet'inki bu görev için çok iyi değil) ve children
nesnenin birkaç seviyesini ( ) inceleyin :
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>
Not : Ne tür bir veri ortamı oluşturacağınızı bilmiyorum, ama taksonomik aşamalardan gerçekten kaçınmalısınız. Bütün Linnaean taksonomisi modası geçmiş, artık rütbe kullanmıyoruz: filogenetik sistematik 60'lı yılların ortalarında geliştirildiğinden, taksonomik bir sıra olmaksızın sadece taksonları kullanıyoruz (burada evrim biyolojisi öğretmeni). Ayrıca, 7 milyondan fazla türü tanımladığımız için bu 7 milyon satırı merak ediyorum!
nan
Magnoliopsida içeren Phylum için bir fark ettim . Bu nedirnan
? Phylum Anthophyta veya alternatif olarak Manolya'dır (eski Phylum Angiospermae'dir).