15

data.frameオブジェクトがあります。簡単な例:

> data.frame(x=c('A','A','B','B','B'), y=c('Ab','Ac','Ba', 'Ba','Bd'), z=c('Abb','Acc','Bad', 'Bae','Bdd'))
  x  y   z
1 A Ab Abb
2 A Ac Acc
3 B Ba Bad
4 B Ba Bae
5 B Bd Bdd

実際のデータには、さらに多くの行と列があります。このような樹状図のネストされたツリー構造オブジェクトを作成するにはどうすればよいですか?

         |---Ab---Abb
     A---|
     |   |---Ac---Acc
   --|                 /--Bad 
     |   |---Ba-------|
     B---|             \--Bae
         |---Bb---Bdd
4

2 に答える 2

18

data.frameからNewickへ

私は計算系統学の博士号を取得し、このコードを作成する途中のどこかで、この非標準形式(系統発生の意味で)のデータを取得するときに1〜2回使用しました。スクリプトは、まるでツリーであるかのようにデータフレームをトラバースし、途中でNewick文字列に貼り付けます。これは標準形式であり、任意の種類のツリーオブジェクトに変換できます。

スクリプトは最適化できると思いますが(あまり使用しないので、全体的な効率が低下します)、少なくとも、ハードドライブに散らばっているほこりを集めるよりも共有する方がよいでしょう。

    ## recursion function
    traverse <- function(a,i,innerl){
        if(i < (ncol(df))){
            alevelinner <- as.character(unique(df[which(as.character(df[,i])==a),i+1]))
            desc <- NULL
            if(length(alevelinner) == 1) (newickout <- traverse(alevelinner,i+1,innerl))
            else {
                for(b in alevelinner) desc <- c(desc,traverse(b,i+1,innerl))
                il <- NULL; if(innerl==TRUE) il <- a
                (newickout <- paste("(",paste(desc,collapse=","),")",il,sep=""))
            }
        }
        else { (newickout <- a) }
    }

    ## data.frame to newick function
    df2newick <- function(df, innerlabel=FALSE){
        alevel <- as.character(unique(df[,1]))
        newick <- NULL
        for(x in alevel) newick <- c(newick,traverse(x,1,innerlabel))
        (newick <- paste("(",paste(newick,collapse=","),");",sep=""))
    }

main関数df2newick()は2つの引数を取ります。

  • dfこれは変換されるデータフレームです(クラスdata.frameのオブジェクト)
  • innerlabelこれは、関数に内部ノードのラベルを書き込むように指示します(bulean)

あなたの例でそれを示すために:

    df <- data.frame(x=c('A','A','B','B','B'), y=c('Ab','Ac','Ba', 'Ba','Bd'), z=c('Abb','Acc','Bad', 'Bae','Bdd'))
    myNewick <- df2newick(df)
    #[1] "((Abb,Acc),((Bad,Bae),Bdd));"

phyloこれでread.tree()、fromapeを使用してクラスのオブジェクトに読み込むことができます。

    library(ape)
    mytree <- read.tree(text=myNewick)
    plot(mytree)

Newick文字列に内部ノードラベルを追加する場合は、次を使用できます。

    myNewick <- df2newick(df, TRUE)
    #[1] "((Abb,Acc)A,((Bad,Bae)Ba,Bdd)B);"

これがお役に立てば幸いです(そしておそらく私の博士号は完全な時間の腰ではありませんでした;-)


データフレーム形式に関する追加の注意事項:

ご覧のとおり、df2newick関数は、1つの子を持つ内部モードを無視します(とにかく、ほとんどの系統発生方法で使用するのが最適です...私にのみ関連していました)。このdfスクリプトで最初に取得して使用したオブジェクトは、次の形式でした。

    df <- data.frame(x=c('A','A','B','B','B'), y=c('Abb','Acc','Ba', 'Ba','Bdd'), z=c('Abb','Acc','Bad', 'Bae','Bdd'))

あなたのものと非常に似ています...しかし、「内部単一の子ノード」はそれらの子と同じ名前を持っていましたが、このノードにも異なる内部名があり、名前は無視されます...関連性がないかもしれませんが、あなたはできます次のように、再帰関数の一部を無視してください。

    traverse <- function(a,i,innerl){
        if(i < (ncol(df))){
            alevelinner <- as.character(unique(df[which(as.character(df[,i])==a),i+1]))
            desc <- NULL
            ##if(length(alevelinner) == 1) (newickout <- traverse(alevelinner,i+1,innerl))
            ##else {
                for(b in alevelinner) desc <- c(desc,traverse(b,i+1,innerl))
                il <- NULL; if(innerl==TRUE) il <- a
                (newickout <- paste("(",paste(desc,collapse=","),")",il,sep=""))
            ##}
        }
        else { (newickout <- a) }
    }

そして、あなたはこのようなものを得るでしょう:

    [1] "(((Abb)Ab,(Acc)Ac)A,((Bad,Bae)Ba,(Bdd)Bd)B);"

これは私には本当に奇妙に見えますが、念のために追加します。これは、元のデータフレームからのすべての情報が実際に含まれているためです。

于 2013-03-12T19:44:20.257 に答える
1

Rの樹状図の内部構造についてはよくわかりませんが、次のコードは、探している階層を持つネストされたリスト構造を作成します。

stree = function(x,level=0) {
#x is a string vector
#resultis a hierarchical structure of lists (that contains lists, etc.)
#the names of the lists are the node values.

level = level+1
if (length(x)==1) {
    result = list()
    result[[substring(x[1],level)]]=list()
    return(result)
}
result=list()
this.level = substring(x,level,level)
next.levels = unique(this.level)
for (p in next.levels) {
    if (p=="") {
        result$p = list()
    } else {
        ids = which(this.level==p)
        result[[p]] = stree(x[ids],level)
    }
}
result
}

文字列のベクトルを操作します。したがって、データフレームの場合は、stree(as.character(df [、3]))を呼び出す必要があります。

お役に立てれば。

于 2013-03-12T07:41:53.850 に答える