5

以下は、サンプル セッションの出力の抜粋です。その中で、関数を使用してマトリックスを作成し、matrix()それを関数を使用してデータフレームに変換するだけas.data.frame()です。2 番目のセクションでは、マトリックスも作成しますが、別のプロセス (機能させたいプロセス) を使用str()しますが、同様の出力が得られますが、データフレームに変換するときにエラーが発生します。何か案は?

編集: 最後に、マトリックスをマトリックスに (再) キャストし、それをデータ フレームに変換する行を追加しました。それは機能しますが、データ フレームとしてキャストできなかったのstr()出力に見られるように、再キャストする必要はありません。test_mxだから私は修正する方法を知っていますが、そうするためにその余分なステップを実行する必要がある理由がわかりません.

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?
4

2 に答える 2

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"

うーん。このcast_dfクラスは何ですか?「reshape」メソッドがなくなり、いくつかの新しいメソッドが定義されていることがわかりました。たとえば、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

上記の ^^ の 1 番目と 2 番目の方法as.matrix、 の 4 番目と 5 番目の方法に注意してくださいas.data.frame

これは何を意味するのでしょうか?さて、作成した後にいくつかの行を書き込んで、 をtest_mxに変換data.frameしましたmatrixrownamesこれは主に、最初の列が最終的にマトリックス全体を文字マトリックスに変換しないようにしたかったためです。

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

「reshape」はすでにカスタマイズされた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

うーん。as.matrix直接使用するattributesと、「reshape」パッケージが追加するすべてが保持されますが、プロセスを手動で実行すると、同じclassであると主張されますが、すべてのカスタムattributesが削除されています.

だから何?

R はそれが であると考えてtest_mxいるためcast_matrix、 を呼び出すとas.data.frame、実際には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 つのオプションがあります。

  1. 「reshape2」へのアップグレード -- 良いアドバイスですが、切り替えを行っていない人がまだたくさんいることを覚えておいてください。

  2. str「reshape」を正しく使用するには、それが作成する、classes 、および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
    

はぁ。終わり....

于 2013-07-26T05:36:08.697 に答える