2016-12-22 16 views
0

ID(文字列)列の後に異なるサンプルの測定値を含むいくつかの数値列が続く大きな表(数十万行)があります。文字列を含むdata.tableに対して数値演算を実行

数値データのスケーリングやロギング、分散に基づくフィルタリング、プロットなどの数値演算を行う必要があります。これまでのやり方は、データの数値部分をサブセット化することでした新しい変数を作成し、それに応じて処理します。

f_na2zero(dt) 
dt.num <- dt[,!c("Seq"),with=F] 
dt.scaled <- (dt.num + 1)/colSums(dt.num) # +1 to avoid NaN due to logging 
dt.log <- log10(dt.scaled) 

newdt <- data.table("Seq" = dt$Seq, dt.log) 
dt.filtered <- newdt[nchar(Seq) == 207, ] 
dt.A <- dt.filtered[, c("Seq", "Lib", "A5_1", "A5_2", "A5_3"), with=F] 
dt.B <- dt.filtered[, c("Seq", "Lib", "B5_1", "B5_2", "B5-3"), with=F] 

ind.A.highvar <- which(apply(dt.A, 1, var) > sd(as.matrix(dt.A))) 
ind.B.highvar <- which(apply(dt.B, 1, var) > sd(as.matrix(dt.B))) 
ind.A.highvar2 <- which(apply(dt.A, 1, var) > 2*sd(as.matrix(dt.A))) 
ind.B.highvar2 <- which(apply(dt.B, 1, var) > 2*sd(as.matrix(dt.B))) 

A.highvar <- dt.A[ind.A.highvar, !c("Seq"), with=F] 
A.highvar2 <- dt.A[ind.A.highvar2, !c("Seq"), with=F] 
B.highvar <- dt.B[ind.B.highvar, !c("Seq"), with=F] 
B.highvar2 <- dt.B[ind.B.highvar2, !c("Seq"), with=F] 

par(mfrow=c(2,2)) 
# plotLines takes a matrix and plots each column as a line, returns indices where data[1,] < data[4,] is true 
seqs.A1 <- plotLines(t(A.highvar),"1 Sigma A",c("Lib", "A5-1", "A5-2", "A5-3")) 
seqs.B1 <- plotLines(t(B.highvar),"1 Sigma B",c("Lib", "B5-1", "B5-2", "B5-3")) 
seqs.A2 <- plotLines(t(A.highvar2),"2 Sigma A",c("Lib", "A5-1", "A5-2", "A5-3")) 
seqs.B2 <- plotLines(t(B.highvar2),"2 Sigma B",c("Lib", "B5-1", "B5-2", "B5-3")) 

問題は、私は、そのデータを利用することができるようにするIDを必要とすることで、私は道に沿って異なる基準に基づいてフィルタリングするように行番号が変化。私は、新しいテーブルと変数を常に保存せずに、データを処理する簡単な方法が必要だと考えましたが、data.tableインデックススキームを理解できません(それを言及する前に、introduction to data.table vignetteを読んでいます)

この文脈で

ので、具体的な質問:

  1. は、データテーブルの一部の列の数値演算を行うことが可能です(つまり、スキップ列「配列」は、ログを行うときは、変換、または論理的にベースのインデックス分散)を経由することなく、

  2. 論理関数に基づいて行をフィルタリングし、特定の列を同時に調べるにはどうすればよいですか? .SDまたは.SDcolumnsを使用する場合は、グループ化演算子byを使用する必要がありますか?

編集ローランドさんのコメントを1として、ここで私が働いているデータの種類を再現する小さなスクリプトです。ごめんなさい

dt <- data.table("Seq" = stringi::stri_rand_strings(100000,200,"[A-Z]"), matrix(rnorm(n = 700000, mean=-3, sd = 1.5), nrow = 100000, ncol = 7, dimnames = list(NULL,c("A5_1","A5_2","A5_3","B5_1", "B5_2","B5_3","Lib")))) 
+0

最小限の再現性の例を提供してください。行を '適用する '場合は間違っています。 data.tableをlong形式に ''溶かすべきでしょう。 – Roland

+0

@Rolandは、私が持っているデータの種類を作成する1つのライナーを追加しました。私はしかし、適用についてのあなたのコメントに従っていない..データはすでに特定の数十万行が長いです。適用すると、各行の測定値のばらつきがわかりますが、何が問題なのかはわかりません。 – posdef

+0

(1)はい、そのために '.SDcols'を使うことができます。ループする列名を指定するだけです。 (2a)あなたが言及したビネットのポイント1-fを見てください。 (2b) 'by'を使う必要はありません。 – Jaap

答えて

2

は、ここに(?Seq列で)再現可能なものは何もないも、あなたの例では最小限でも、それは正確にあなたが達成したいのかを説明ありません。

しかし、多分これは私が長い形式で何を意味するかを示しています。

dt <- melt(dt, id.vars = "Id") 
dt[, ind := .GRP, by = Id] 

library(ggplot2) 
stdev <- sd(dt[, value]) 
ggplot(dt[, if(var(value) > (2 * stdev)) .SD, by = Id], #filter 
     aes(x = ind, y = value, color = variable)) + 
    geom_line() 
関連する問題