2012-04-10 11 views
5

Vorrei esportare un hclust-dendrogramma da R in una tabella dati per importarlo successivamente in un altro software ("fatto in casa"). str(unclass(fit)) fornisce una panoramica testuale per il dendrogramma, ma quello che sto cercando è in realtà una tabella numerica. Ho esaminato il pacchetto ctc del bioconduttore, ma l'output che sta producendo sembra un po 'criptico. Vorrei avere qualcosa di simile a questa tabella: http://stn.spotfire.com/spotfire_client_help/heat/heat_importing_exporting_dendrograms.htm C'è un modo per ottenere questo da un oggetto hclust in R?Esportare il dendrogramma come tabella in R

risposta

1

C'è pacchetto che fa esattamente opposto di ciò che si vuole - Labeltodendro ;-)

Ma seriamente, non puoi semplicemente estrarre manualmente gli elementi da hclust oggetto (ad esempio $merge, $height, $order) e creare su misura tabella dagli elementi estratti?

3

Nel caso in cui qualcuno sia interessato anche all'esportazione di dendrogrammi, ecco la mia soluzione. Molto probabilmente, non è il migliore in quanto ho iniziato a usare R solo di recente, ma almeno funziona. Quindi i suggerimenti su come migliorare il codice sono i benvenuti.

Quindi, se hr è il mio oggetto hclust e df è i miei dati, la prima colonna dei quali contiene un semplice indice a partire da 0, ed i nomi di riga sono i nomi degli oggetti cluster:

# Retrieve the leaf order (row name and its position within the leaves) 
leaf.order <- matrix(data=NA, ncol=2, nrow=nrow(df), 
       dimnames=list(c(), c("row.num", "row.name"))) 
leaf.order[,2] <- hr$labels[hr$order] 
for (i in 1:nrow(leaf.order)) { 
    leaf.order[which(leaf.order[,2] %in% rownames(df[i,])),1] <- df[i,1] 
} 
leaf.order <- as.data.frame(leaf.order) 

hr.merge <- hr$merge 
n <- max(df[,1]) 

# Re-index all clustered leaves and nodes. First, all leaves are indexed starting from 0. 
# Next, all nodes are indexed starting from max. index leave + 1. 
for (i in 1:length(hr.merge)) { 
    if (hr.merge[i]<0) {hr.merge[i] <- abs(hr.merge[i])-1} 
    else { hr.merge[i] <- (hr.merge[i]+n) } 
} 
node.id <- c(0:length(hr.merge)) 

# Generate dendrogram matrix with node index in the first column. 
dend <- matrix(data=NA, nrow=length(node.id), ncol=6, 
      dimnames=list(c(0:(length(node.id)-1)), 
       c("node.id", "parent.id", "pruning.level", 
       "height", "leaf.order", "row.name"))) 
dend[,1] <- c(0:((2*nrow(df))-2)) # Insert a leaf/node index 

# Calculate parent ID for each leaf/node: 
# 1) For each leaf/node index, find the corresponding row number within the merge-table. 
# 2) Add the maximum leaf index to the row number as indexing the nodes starts after indexing all the leaves. 
for (i in 1:(nrow(dend)-1)) { 
    dend[i,2] <- row(hr.merge)[which(hr.merge %in% dend[i,1])]+n 
} 

# Generate table with indexing of all leaves (1st column) and inserting the corresponding row names into the 3rd column. 
hr.order <- matrix(data=NA, 
      nrow=length(hr$labels), ncol=3, 
      dimnames=list(c(), c("order.number", "leaf.id", "row.name"))) 
hr.order[,1] <- c(0:(nrow(hr.order)-1)) 
hr.order[,3] <- t(hr$labels[hr$order]) 
hr.order <- data.frame(hr.order) 
hr.order[,1] <- as.numeric(hr.order[,1]) 

# Assign the row name to each leaf. 
dend <- as.data.frame(dend) 
for (i in 1:nrow(df)) { 
     dend[which(dend[,1] %in% df[i,1]),6] <- rownames(df[i,]) 
} 

# Assign the position on the dendrogram (from left to right) to each leaf. 
for (i in 1:nrow(hr.order)) { 
     dend[which(dend[,6] %in% hr.order[i,3]),5] <- hr.order[i,1]-1 
} 

# Insert height for each node. 
dend[c((n+2):nrow(dend)),4] <- hr$height 

# All leaves get the highest possible pruning level 
dend[which(dend[,1] <= n),3] <- nrow(hr.merge) 

# The nodes get a decreasing index starting from the pruning level of the 
# leaves minus 1 and up to 0 

for (i in (n+2):nrow(dend)) { 
    if ((dend[i,4] != dend[(i-1),4]) || is.na(dend[(i-1),4])){ 
     dend[i,3] <- dend[(i-1),3]-1} 
     else { dend[i,3] <- dend[(i-1),3] } 
} 
dend[,3] <- dend[,3]-min(dend[,3]) 

dend <- dend[order(-node.id),] 

# Write results table. 
write.table(dend, file="path", sep=";", row.names=F) 
+0

I ho appena usato questo codice e ha funzionato perfettamente. La grande difficoltà per me? Leggendo le indicazioni su quali dati di input erano richiesti - quella descrizione del frame dei dati "df" è effettivamente importante, gente. – eleanorahowe

+0

@Eleanor Sono felice che tu l'abbia trovato utile. Hai ragione, il codice si basa su una particolare struttura del frame di dati di input. Spero tu non abbia passato troppo tempo a capirlo. – AnjaM