私はdata.tablesが初めてで、次のようなDNAゲノム座標を含むテーブルがあります。
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
約 200 万行のテーブルの各行に適用するカスタム関数を作成しました。GenomicFeatures の mapToTranscripts を使用して、2 つの関連する値を文字列と新しい座標の形式で取得します。次のように、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]
そして、このエラーが発生します。これは、関数が行ごとに 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 つの値が返されると想定しました。また、 ifステートメントを使用して、関数が空の値を返さないようにしました。
次に、関数のこのモック バージョンを試しました。
get_feature <- function(dt) {
return('I should be returned once for each row')
}
そしてそれを次のように呼び出しました:
new.table <- counts[, get_feature(.SD), by = .I]
元の長さではなく、1行のデータテーブルを作成します。したがって、私の関数、またはおそらく私がそれを呼び出している方法は、結果のベクトルの要素を何らかの形で折りたたんでいると結論付けました。私は何を間違っていますか?
更新 (解決策あり): @StatLearner が指摘したように、この回答では、で説明されているように?data.table
、(のように).I
での使用のみを目的としていることが説明されています。したがって、は と同等であり、適切な構文は、行番号でグループ化し、関数を行ごとに適用するためのものです。j
DT[i,j,by=]
by=.I
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)]
mapFromTranscripts
次に、 fromGenomicFeatures
パッケージを使用してゲノムにマップし直して、data.tables
結合を使用して元のテーブルから情報を取得できるようにしました。