2013-07-25 5 views
5

以下は、サンプルセッションの出力をまとめたものです。その中で、私はmatrix()関数を持つ行列を作成し、as.data.frame()関数を持つデータフレームに変換するだけです。 2番目のセクションでは、マトリックスも作成しますが、別のプロセス(作業をしたいもの)を使用しますが、str()は類似の出力を与えますが、データフレームに変換するとエラーが発生します。何か案は?行列をデータフレームに変換する:あるケースで動作し、別のケースでは動作しません。

EDIT:最後に、I(再)行列を行列にキャストした行を追加し、それをデータフレームに変換します。それは動作しますが、データフレームとしてキャストできないtest_mxの出力str()の出力に表示されているとおりに再作成する必要はありません。だから私は修正する方法を知っているが、なぜ私はそうするために余分なステップを行う必要があるのか​​分からない。後者は時代遅れであるとして

R version 2.15.2 (2012-10-26) -- "Trick or Treat" 

> library(reshape) 
> ## This works 
> ## ========== 
> tmx = matrix(1:12*0.1, ncol=4) 
> rownames(tmx) = c("A", "B", "C") 
> colnames(tmx) = 0:3 
> tmx 
    0 1 2 3 
A 0.1 0.4 0.7 1.0 
B 0.2 0.5 0.8 1.1 
C 0.3 0.6 0.9 1.2 
> 
> str(tmx) 
num [1:3, 1:4] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : chr [1:3] "A" "B" "C" 
    ..$ : chr [1:4] "0" "1" "2" "3" 
> as.data.frame(tmx) 
    0 1 2 3 
A 0.1 0.4 0.7 1.0 
B 0.2 0.5 0.8 1.1 
C 0.3 0.6 0.9 1.2 
> 
> 
> 
> ## This does not 
> ## ============= 
> t = 0:3 
> thesd = 0.1 
> dat = data.frame(
+  a1 = sin(2*pi*t/length(t)) + rnorm(t, sd=thesd), 
+  b1 = sin(2*pi*t/length(t) - pi) + rnorm(t, sd=thesd), 
+  c1 = sin(2*pi*t/length(t) - pi/2) + rnorm(t, sd=thesd), 
+  t = t 
+) 
> 
> test_mx = cast(melt(dat, id.vars="t"), variable ~ t) 
> tmp_rownames = as.character(test_mx[,1]) 
> test_mx = test_mx[,-1] 
> tmp_colnames = colnames(test_mx) 
> test_mx = as.matrix(test_mx) 
> rownames(test_mx) = tmp_rownames 
> colnames(test_mx) = tmp_colnames 
> 
> str(test_mx) 
num [1:3, 1:4] 0.06211 -0.00596 -1.09718 1.1555 -0.96443 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : chr [1:3] "a1" "b1" "c1" 
    ..$ : chr [1:4] "0" "1" "2" "3" 
> as.data.frame(test_mx) 
Error in data.frame(rrownames(x), unx, check.names = FALSE) : 
    arguments imply differing number of rows: 0, 3 
> 
> ## But this does work 
> as.data.frame(as.matrix(test_mx)) 
      0   1   2   3 
a1 -0.16166693 0.97479282 0.01471777 -1.01517539 
b1 -0.01012797 -0.97745698 -0.12667287 0.96542412 
c1 -1.07217297 0.06783235 1.12068282 -0.02012263 

> ## why? 
+0

私は 'test_mx = cast(melt(dat、id.vars =" t ")、変数〜t)'を使いました。 'パッケージ。それがなければ、私は 'エラー:関数を見つけることができませんでした 'というキャストを取得します。 – mpettis

+0

私は[この回答で](http://stackoverflow.com/a/17873683/1270695)で説明したように、 'class'とそれに関連する' methods'を見てください。 – A5C1D2H2I1M1N2O1R2T1

+0

また、今後、あなたのコードから厄介な '>'と '+'記号を削除して、コードをコピー&ペーストしてテストしにくくしてください! – A5C1D2H2I1M1N2O1R2T1

答えて

5

あなたは、ないreshapereshape2を、使用する必要があります。

さらにcastdcastまたはacastで変更してください。

as.data.frame(test_mx) 
      0   1   2   3 
1 -0.08120468 0.97593052 -0.006127179 -1.15107784 
2 -0.04165681 -1.02810193 0.004637454 0.99042403 
3 -0.87862063 0.07346341 1.019113669 -0.01769976 
+0

ありがとう!それはデータフレームへのキャストを解決するだけでなく、行と列の名前を正しく取得するために、処理を行う必要はありませんでした。私はここで完全なソリューションの例を書きました:http://pastebin.com/B2uEPy8M。ソリューションコードとしてそれを使用しても構わないと思いますか? – mpettis

11

@ agstudyの答えはあなたの問題を解決して、最新のパッケージを最新にあなたを取得しますが、それはこれがなぜ起こるかを理解しようとするにはなりません。

理由を理解するには、test_mx = cast(melt(dat, id.vars="t"), variable ~ t)の行に戻ってください。ここでは2つのオブジェクトを作成していくつかの比較を行います:

test_mx <- test_mx_cast <- cast(melt(dat, id.vars="t"), variable ~ t) 
class(test_mx) 
# [1] "cast_df" "data.frame" 
class(test_mx_cast) 
# [1] "cast_df" "data.frame" 

Hmm。これはcast_dfクラスとは何ですか? 「再形成」メソッドがいくつかの新しいメソッドに移行し、定義されていることが判明しました。例えば、methods(as.data.frame)又はmethods(as.matrix)を参照:

> methods(as.matrix) 
[1] as.matrix.cast_df  as.matrix.cast_matrix as.matrix.data.frame as.matrix.default  
[5] as.matrix.dist*  as.matrix.noquote  as.matrix.POSIXlt  as.matrix.raster*  

    Non-visible functions are asterisked 
> methods(as.data.frame) 
[1] as.data.frame.aovproj*  as.data.frame.array   as.data.frame.AsIs   
[4] as.data.frame.cast_df   as.data.frame.cast_matrix  as.data.frame.character  
[7] as.data.frame.complex   as.data.frame.data.frame  as.data.frame.Date   
[10] as.data.frame.default   as.data.frame.difftime  as.data.frame.factor   
[13] as.data.frame.ftable*   as.data.frame.function*  as.data.frame.idf*   
[16] as.data.frame.integer   as.data.frame.list   as.data.frame.logical   
[19] as.data.frame.logLik*   as.data.frame.matrix   as.data.frame.model.matrix 
[22] as.data.frame.numeric   as.data.frame.numeric_version as.data.frame.ordered   
[25] as.data.frame.POSIXct   as.data.frame.POSIXlt   as.data.frame.raw    
[28] as.data.frame.table   as.data.frame.ts    as.data.frame.vector   

    Non-visible functions are asterisked 

注意^^上記as.data.frameためas.matrixと第四及び第五の方法のための第一及び第二の方法。

これはどういう意味ですか?さて、test_mxを作成してdata.framematrixに変換した後、いくつかの行を書きました。これは、ほとんどの場合、最初の列がrownamesとなってしまったことを確認し、行列全体を文字マトリックスに強制しないためです。

tmp_rownames = as.character(test_mx[,1]) 
test_mx = test_mx[,-1] 
tmp_colnames = colnames(test_mx) 
test_mx = as.matrix(test_mx) 
rownames(test_mx) = tmp_rownames 
colnames(test_mx) = tmp_colnames 
test_mx 
#    0   1   2   3 
# a1 -0.079811371 0.82820704 -0.193860367 -1.1269632 
# b1 -0.009402418 -1.19348155 -0.004519269 0.8921427 
# c1 -0.784163111 -0.01340952 0.966208235 0.0135557 

「再構築」は、すでにあなたが実際にそれを行う必要はありませんでした、カスタマイズされたas.matrixメソッドを定義しているので!

as.matrix(test_mx_cast) 
#    0   1   2   3 
# a1 -0.079811371 0.82820704 -0.193860367 -1.1269632 
# b1 -0.009402418 -1.19348155 -0.004519269 0.8921427 
# c1 -0.784163111 -0.01340952 0.966208235 0.0135557 

しかし、それでもすべてが正確には答えられません。さらに理解するために、2つの行列を今比較する:

> test_mx_cast_matrix <- as.matrix(test_mx_cast) 
> class(test_mx) 
[1] "cast_matrix" "matrix"  
> class(test_mx_cast_matrix) 
[1] "cast_matrix" "matrix"  
> str(test_mx) 
num [1:3, 1:4] -0.0798 -0.0094 -0.7842 0.8282 -1.1935 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : chr [1:3] "a1" "b1" "c1" 
    ..$ : chr [1:4] "0" "1" "2" "3" 
> str(test_mx_cast_matrix) 
num [1:3, 1:4] -0.0798 -0.0094 -0.7842 0.8282 -1.1935 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : chr [1:3] "a1" "b1" "c1" 
    ..$ : chr [1:4] "0" "1" "2" "3" 
- attr(*, "idvars")= chr "variable" 
- attr(*, "rdimnames")=List of 2 
    ..$ :'data.frame': 3 obs. of 1 variable: 
    .. ..$ variable: Factor w/ 3 levels "a1","b1","c1": 1 2 3 
    ..$ :'data.frame': 4 obs. of 1 variable: 
    .. ..$ t: int [1:4] 0 1 2 3 

Hmmm。 as.matrixを直接使用すると、 "reshape"パッケージが追加するattributesのすべてが保持されますが、手作業では同じclassと表示されますが、すべてのカスタムattributesは削除されています。

だから何ですか?Rは、あなたがas.data.frameを呼び出すときtest_mxは、cast_matrixあると思うので、

まあ、それは実際にas.data.frame.cast_matrix、ないas.data.frame.matrix呼び出します。

as.data.frame.cast_matrixが定義されているかを見てみると、それらのattributes不可欠再作成するためにあなたのdata.frame、したがって、あなたのエラーがあります。ここでは、関数の中身は以下のとおりです。

> as.data.frame.cast_matrix 
function (x, row.names, optional, ...) 
{ 
    unx <- unclass(x) 
    colnames(unx) <- rownames(rcolnames(x)) 
    r.df <- data.frame(rrownames(x), unx, check.names = FALSE) 
    class(r.df) <- c("cast_df", "data.frame") 
    attr(r.df, "idvars") <- attr(x, "idvars") 
    attr(r.df, "rdimnames") <- attr(x, "rdimnames") 
    rownames(r.df) <- 1:nrow(r.df) 
    r.df 
} 
<environment: namespace:reshape> 

だから、あなたは今、3つのオプションがあります:「reshape2」へ

  1. アップグレード - 良いアドバイスが、良いがまだあることを心に留めておくと切り替えを気にしていない人の数。

  2. strclass、およびattributesで作成したオブジェクトをもう少し見る必要がある「変形」を正しく使用してください。ここで「正しく」使用するとas.data.frame(test_mx_cast_matrix)を使用していました。

  3. あなたが使用したいmethodを指定します(これは、パッケージが再定義メソッドであるかどうかわからないときにはかなり安全です。新しいクラスを作成するときには、新しいメソッドが作成されているか)。比較:

    > as.data.frame(test_mx)  ## Calls `as.data.frame.cast_matrix` ERROR! 
    Error in data.frame(rrownames(x), unx, check.names = FALSE) : 
        arguments imply differing number of rows: 0, 3 
    > as.data.frame.matrix(test_mx) ## Specifies the `as.data.frame` method. WORKS! 
           0   1   2   3 
    a1 -0.079811371 0.82820704 -0.193860367 -1.1269632 
    b1 -0.009402418 -1.19348155 -0.004519269 0.8921427 
    c1 -0.784163111 -0.01340952 0.966208235 0.0135557 
    

ため息。最後に....

+0

努力のために+1してください。これはあなたの答えの中の各単語の '1.3e-3'投票に等しいです。 – thelatemail

+0

@thelatemail、各単語に0より良い! – A5C1D2H2I1M1N2O1R2T1

+0

徹底的な答えをありがとう! 「正しい形を使用する」のように思えるのはちょっと難しいですね。私のように、ソリューションをハッキングするのではなく、コンバートを行う最も簡単な方法の習慣について、どこで学んでいますか? – mpettis

関連する問題