私はdata.tablesに新しいの一種だと私はこのようなDNAゲノム座標を含むテーブルを持っているの間違った金額を返します。行でdata.tableにカスタム関数を適用すると、値
chrom pause strand coverage
1: 1 3025794 + 1
2: 1 3102057 + 2
3: 1 3102058 + 2
4: 1 3102078 + 1
5: 1 3108840 - 1
6: 1 3133041 + 1
私はカスタムを書きました関数を2百万回の行テーブルの各行に適用するには、GenomicFeaturesのmapToTranscriptsを使用して、関連する2つの値を文字列と新しい座標の形式で取得します。私はこのように、二つの新しいコラムで私のテーブルにそれらを追加したい:
chrom pause strand coverage transcriptID CDS
1: 1 3025794 + 1 ENSMUST00000116652 196
2: 1 3102057 + 2 ENSMUST00000116652 35
3: 1 3102058 + 2 ENSMUST00000156816 888
4: 1 3102078 + 1 ENSMUST00000156816 883
5: 1 3108840 - 1 ENSMUST00000156816 882
6: 1 3133041 + 1 ENSMUST00000156816 880
機能は以下の通りです:
get_feature <- function(dt){
coordinate <- GRanges(dt$chrom, IRanges(dt$pause, width = 1), dt$strand)
hit <- mapToTranscripts(coordinate, cds_canonical, ignore.strand = FALSE)
tx_id <- tx_names[as.character(seqnames(hit))]
cds_coordinate <- sapply(ranges(hit), '[[', 1)
if(length(tx_id) == 0 || length(cds_coordinate) == 0) {
out <- list('NaN', 0)
} else {
out <- list(tx_id, cds_coordinate)
}
return(out)
}
その後、私は:
counts[, c("transcriptID", "CDS"):=get_feature(.SD), by = .I]
そしてI行ごとに1つの新しい要素ではなく、関数が元の表よりも短い2つのリストを返すことを示すこのエラーを取得します。
Warning messages:
1: In `[.data.table`(counts, , `:=`(c("transcriptID", "CDS"), ... :
Supplied 1112452 items to be assigned to 1886614 items of column 'transcriptID' (recycled leaving remainder of 774162 items).
2: In `[.data.table`(counts, , `:=`(c("transcriptID", "CDS"), ... :
Supplied 1112452 items to be assigned to 1886614 items of column 'CDS' (recycled leaving remainder of 774162 items).
.I演算子を使用すると、行ベースで関数が適用され、行ごとに1つの値が返されると想定しました。ステートメントの場合、を使用して関数が空の値を返さないことを確認しました。
そしてIは、関数のこの模擬バージョン試み:
get_feature <- function(dt) {
return('I should be returned once for each row')
}
および、このように呼ばれる:
new.table <- counts[, get_feature(.SD), by = .I]
が、1つのつではなく、元の長さの、1行のデータテーブルを作成します。だから、私の機能、あるいは私がそれを呼んでいる方法は、何らかの形で結果のベクトルの要素を崩壊させていると結論づけました。私は間違って何をしていますか?
更新(溶液による): @StatLearnerが指摘したように、?data.table
で説明したように、ことthis answerに説明され、.I
のみ(DT[i,j,by=]
のように)j
における使用のために意図されています。従って、はby=NULL
と等価であり、適切な構文はby=1:nrow(dt)
であり、行番号ごとにグループ化し、関数を行ごとに適用する。
残念ながら、私の特定のケースでは、これは全く効率が悪く、100行で20秒の実行時間を計算しました。私の3,600万行のデータセットについて、完了までに3ヶ月かかる。
私の場合、私はあきらめてこのようなテーブル全体にmapToTranscripts
関数を使用しなければなりませんでした。これは数秒かかり、明らかに意図された使用でした。
get_features <- function(dt){
coordinate <- GRanges(dt$chrom, IRanges(dt$pause, width = 1), dt$strand) # define coordinate
hits <- mapToTranscripts(coordinate, cds_canonical, ignore.strand = FALSE) # map it to a transcript
tx_hit <- as.character(seqnames(hits)) # get transcript number
tx_id <- tx_names[tx_hit] # get transcript name from translation table
return(data.table('transcriptID'= tx_id,
'CDS_coordinate' = start(hits))
}
density <- counts[, get_features(.SD)]
私はdata.tables
を使用することができますので、その後GenomicFeatures
パッケージからmapFromTranscripts
を使用してバックゲノムへのマッピングは、私がやろうとしていたものの本来の目的であった、元のテーブルから情報を取得するために参加します。
良い答え@StatLearner。ようこそ! – rosscova
これは本当に本当です、@StatLearner、私は 'by = NULL'でチェックし、結果は同じです。 'by = 1:NROW(dt)'を使うと、私の望むように関数が適用されますが、それは非常に遅いので、別の回避策を探す必要がありました。私はこの機能を私が望んでいた方法で使うことはできませんが、今日は 'data.tables'について多くのことを学んだので、どうもありがとう! –
PS:面白いのは、[この他の回答]から「by = .I」というアイデアが得られたことです(http://stackoverflow.com/questions/25431307/r-data-table-apply-function-to-rows -using-columns-as-arguments)_ Google検索で表示される最初のものです_ "各行のデータテーブルに関数を適用" _。誰かが私と同じアイデアを持っている場合に備えて、そこに言及した答えをリンクします。 –