3

私はそのように見える55000行のテーブルを持っています(左のテーブル): サンプルテーブル

(サンプルデータを生成するコードは以下です)

ここで、このテーブルのすべての行を 6 行に変換する必要があります。各行には「六量体」の文字が 1 つ含まれています (写真の右の表)。

# input for the function is one row of source table, output is 6 rows
splithexamer <- function(x){
  dir <- x$dir # strand direction: +1 or -1
  pos <- x$pos # hexamer position
  out <- x[0,] # template of output
  hexamer <- as.character(x$hexamer)
  for (i in 1:nchar(hexamer)) {
    letter <- substr(hexamer, i, i)
    if (dir==1) {newpos <- pos+i-1;}
    else        {newpos <- pos+6-i;}
    y <- x
    y$pos <- newpos
    y$letter <- letter
    out <- rbind(out,y)
  }
  return(out);
} 


# Sample data generation:
set.seed(123)
size <- 55000
letters <- c("G","A","T","C")
df<-data.frame(
  HSid=paste0("Hs.", 1:size),
  hexamer=replicate(n=size, paste0(sample(letters,6,replace=T), collapse="")),
  chr=sample(c(1:23,"X","Y"),size,replace=T),
  pos=sample(1:99999,size,replace=T),
  dir=sample(c(1,-1),size,replace=T)
)

ここで、関数をすべての行に適用する最も効率的な方法について、いくつかのアドバイスを得たいと思います。これまでのところ、次のことを試しました。

# Variant 1: for() with rbind
tmp <- data.frame()
for (i in 1:nrow(df)){
tmp<-rbind(tmp,splithexamer(df[i,]));
}

# Variant 2: for() with direct writing to file
for (i in 1:nrow(df)){
write.table(splithexamer(df[i,]),file="d:/test.txt",append=TRUE,quote=FALSE,col.names=FALSE)
}

# Variant 3: ddply
tmp<-ddply(df, .(HSid), .fun=splithexamer)

# Variant 4: apply - I don't know correct syntax
tmp<-apply(X=df, 1, FUN=splithexamer) # this causes an error

上記のすべてが非常に遅いです。このタスクを解決するためのより良い方法があるかどうか疑問に思っています...

4

1 に答える 1

3

を使用したソリューションdata.table:

df$hexamer <- as.character(df$hexamer)
dt <- data.table(df)
dt[, id := seq_len(nrow(df))]
setkey(dt, "id")
dt.out <- dt[, { mod.pos <- pos:(pos+5); if(dir == -1) mod.pos <- rev(mod.pos); 
                list(split = unlist(strsplit(hexamer, "")), 
                    mod.pos = mod.pos)}, by=id][dt][, id := NULL]
dt.out
#         split mod.pos     HSid hexamer chr   pos dir
#      1:     G   95982     Hs.1  GCTCCA   5 95982   1
#      2:     C   95983     Hs.1  GCTCCA   5 95982   1
#      3:     T   95984     Hs.1  GCTCCA   5 95982   1
#      4:     C   95985     Hs.1  GCTCCA   5 95982   1
#      5:     C   95986     Hs.1  GCTCCA   5 95982   1
#     ---                                             
# 329996:     A   59437 Hs.55000  AATCTG   7 59436   1
# 329997:     T   59438 Hs.55000  AATCTG   7 59436   1
# 329998:     C   59439 Hs.55000  AATCTG   7 59436   1
# 329999:     T   59440 Hs.55000  AATCTG   7 59436   1
# 330000:     G   59441 Hs.55000  AATCTG   7 59436   1

本線の説明:

  • by=idグループ化されid、それらはすべて一意であるため、すべての行で一度に 1 つずつグループ化されます。
  • {}次に、 sets mod.postopos:(pos+6-1)および if内のものはそれをdir == -1逆にします。
  • ここで、list引数:splitを使用して六量体から 6 つのヌクレオチドを作成することによって列を作成し、前のステップで既に計算したものstrsplitも設定します。mod.pos
  • これにより、data.tablewith columnsが生成されますid, split and mod.pos
  • 次の部分は、キー列(ここでは = )に基づいて data.tables で結合を実行する構文[dt]の典型的な使用法です。すべてに6行あるため、この結合中に他のすべての列が複製されます。data.table's X[Y]ididdt

data.table 最初にFAQを見てから、そのドキュメント (イントロ)をご覧になることをお勧めします。これらのリンクは、パッケージをインストールしてロードし、?data.table. また、data.table の機能を実際に理解するために、テスト用の data.table を使用して、そこにある多くの例を 1 つずつ確認することをお勧めします。

お役に立てれば。

于 2013-03-19T15:52:16.947 に答える