2012-01-12 9 views
3

スパースベクトル(R)のリストがあります。このリストを疎な行列に変換する必要があります。 forループを使用して実行すると、時間がかかります。スパースベクトルのリストからスパース行列を作成する

sm<-spMatrix(length(tc2),n.col) 
for(i in 1:length(tc2)){ 
    sm[i,]<-(tc2[i])[[1]]; 
} 

良い方法はありますか?ここで

+0

私は答えるが、いくつかのより多くのことができますガイダンスが必要です。これらのベクトルはどんな種類の疎な形式で保存されていますか?例えば。 'tc2 [[1]]'をたくさんの数値を持つ数値ベクトルとして保存しているのですか?あるいは、疎な行列を使って各ベクトルを表現していますか?あなたは、使用するデータの例を挙げることができますか? – Iterator

+0

@DAF - 私の答えはあなたが求めていたものに対処しましたか?そうであれば、その左側のチェックマークをクリックして受け入れることができます。そうでない場合は、スパース行列に結合したいスパースベクトルのタイプの例を追加できますか?乾杯。 –

+0

@iterator - 私は一歩踏み込んで、「itemset」のリストで始めることができます。つまり、各エントリは行の中に出現するアイテム/単語を示す数字のリストです。私は、このデータの疎なマトリックス表現をしたいと思います。ジョシュのソリューションは小さな例題で動作しますが、10K行と10Kアイテムのサンプルでは、​​メモリが不足します(16G) – DAF

答えて

5

は、2段階のソリューションです:

  • 使用lapply()as(..., "sparseMatrix") 1列sparseMatricesのリストにsparseVectorsのリストを変換します。単一疎行列sparseMatricesを組み合わせること

  • 使用do.call()cBind()。解決策を示唆ためのジョシュ・オブライエンに


require(Matrix) 

# Create a list of sparseVectors 
ss <- as(c(0,0,3, 3.2, 0,0,0,-3), "sparseVector") 
l <- replicate(3, ss) 

# Combine the sparseVectors into a single sparseMatrix 
l <- lapply(l, as, "sparseMatrix") 
do.call(cBind, l) 

# 8 x 3 sparse Matrix of class "dgCMatrix" 
#      
# [1,] . . . 
# [2,] . . . 
# [3,] 3.0 3.0 3.0 
# [4,] 3.2 3.2 3.2 
# [5,] . . . 
# [6,] . . . 
# [7,] . . . 
# [8,] -3.0 -3.0 -3.0 
+1

ありがとう!これは、この例で動作し、私が望むことをします(リストに行があるので、do.callでrBindを使用する点を除いて)。しかし、テキストデータ(10K行と10Kまでの機能、非常にまばらですが)では、do.callは非常に長い時間Rをハングアップするため、終了します。助言がありますか? – DAF

+0

なぜそれが遅いのかわかりません。 'rBind'は実際に再帰的に' rbind2'(一度に2つの行を束縛する)を呼び出すかもしれません。それは**一緒につながるたくさんのベクトルで非常に遅くなるでしょう。しかし、あなたが本当に望むマトリクスを構築するための代替的なアプローチを提案したので、私はこれをさらに調査していきます。乾杯。 –

2

ありがとう:3つのリストを作成し、その後、疎行列を作成します。 私はここで、このためのコードは次のとおりです。

vectorList2Matrix<-function(vectorList){ 
nzCount<-lapply(vectorList, function(x) length([email protected])); 
nz<-sum(do.call(rbind,nzCount)); 
r<-vector(mode="integer",length=nz); 
c<-vector(mode="integer",length=nz); 
v<-vector(mode="integer",length=nz); 
ind<-1; 
for(i in 1:length(vectorList)){ 
    ln<-length(vectorList[[i]]@i); 
    if(ln>0){ 
    r[ind:(ind+ln-1)]<-i; 
    c[ind:(ind+ln-1)]<-vectorList[[i]]@j+1 
    v[ind:(ind+ln-1)]<-vectorList[[i]]@x 
    ind<-ind+ln; 
    } 
} 
return (sparseMatrix(i=r,j=c,x=v)); 
} 
+0

は私を大いに助けました!しかし、同じサイズのベクトルを組み合わせるので、私のソリューションには少し少ないコードが含まれています:http://stackoverflow.com/a/32525837/1075993 –

2

このシナリオで、cbindベクトルの束をINGのは、右のsparse, column-orientedマトリックス(dgCMatrixクラス)に情報をダンプするために完璧に設定されています。

ここでそれを行います機能です。

sv.cbind <- function (...) { 
    input <- lapply(list(...), as, "dsparseVector") 
    thelength <- unique(sapply(input,length)) 
    stopifnot(length(thelength)==1) 
    return(sparseMatrix( 
      x=unlist(lapply(input,slot,"x")), 
      i=unlist(lapply(input,slot,"i")), 
      p=c(0,cumsum(sapply(input,function(x){length([email protected])}))), 
      dims=c(thelength,length(input)) 
     )) 
} 

簡単なテストから、これは強制+ cBindよりも約10倍高速になりそうだ。

require(microbenchmark) 
xx <- lapply(1:10, function (k) { 
      sparseVector(x=rep(1,100), i=sample.int(1e4,100), length=1e4) 
     }) 
microbenchmark(do.call(sv.cbind, xx), do.call(cBind, lapply(xx,as,"sparseMatrix"))) 
# Unit: milliseconds 
#           expr  min  lq  mean median  uq  max neval cld 
#       do.call(sv.cbind, xx) 1.398565 1.464517 1.540172 1.49487 1.55911 3.455421 100 a 
# do.call(cBind, lapply(xx, as, "sparseMatrix")) 16.037890 16.356268 16.956326 16.59854 17.49956 20.256253 100 b 
関連する問題