2013-08-13 3 views
10

applyをdata.frameに使用すると、引数は(暗黙的に)文字に変換されます。例:データフレームへの適用を使用するときの暗黙的な文字変換の回避方法

df <- data.frame(v=1:10, t=1:10) 
df <- transform(df, t2 = as.POSIXlt(t, origin = "2013-08-13")) 
class(df$t2[1]) 
## [1] "POSIXct" "POSIXt" (correct) 

しかし:

apply(df, 1, function(y) class(y["t2"])) 
## [1] "character" "character" "character" "character" "character" "character" 
## [7] "character" "character" "character" "character" 

この変換を避けるためにどのような方法がありますか?または、いつもas.POSIXlt(y["t2"])に変換する必要がありますか?

編集
私のDFが2つのタイムスタンプ(たとえば、t2とt3)といくつかの他のフィールドを持っている(たとえば、V1、V2)。与えられたt2を持つ各行について、t2に最も近いがt2よりも低い(そして同じv1)t3を有するk個(例えば3)の行を見つけ出し、これらの行から統計をv2に戻したい(例えば平均)。私は関数f(t2、v1、df)を書いて、apply(df, 1, function(x) f(y["t2"], y["v1"], df)を使ってすべての行に適用したかっただけです。 Rでこのようなことをするより良い方法はありますか?

+5

本当の答えは、データフレームに 'apply'を使うべきではないということです。あなたは何をしようとしているのですか? – joran

+7

'data.frame'が' matrix'に強制変換されているので、*変換*が発生しています。 –

+0

あなたの編集内容には、実際には2つの異なる質問(IMO)があります。私は適切なデータセット、あなたが試したもの、そしてあなたが望む出力を使って、2番目の質問(あなたの編集)を聞いてみましょう。 –

答えて

4

はのは、説明の中に複数のコメントをラップしてみましょう。

  1. applyの使用はmatrixdata.frameを変換します。この は、最も制限の少ないクラスが使用されることを意味します。この場合、制限が最小の は文字です。
  2. 1applyMARGIN引数を指定しています。これは行によって を適用し、実際にクラスを混合しているのでさらに悪化させます このシナリオでは、ベクトル とdata.frames用に設計されたapplyを使用しています。これは仕事のための適切なツールではありません。

コード::あなたが選択した一般的に

df <- data.frame(v=1:10, t=1:10) 
df <- transform(df, t2 = as.POSIXlt(t, origin = "2013-08-13")) 

sapply(df[, "t2"], class) 
lapply(df[, "t2"], class) 

## [[1]] 
## [1] "POSIXct" "POSIXt" 
## 
## [[2]] 
## [1] "POSIXct" "POSIXt" 
## 
## [[3]] 
## [1] "POSIXct" "POSIXt" 
## 
## . 
## . 
## . 
## 
## [[9]] 
## [1] "POSIXct" "POSIXt" 
## 
## [[10]] 
## [1] "POSIXct" "POSIXt" 

をRMKは、下図のよう 単一t2の列のクラスをつかむために指摘するように、私はlapplyまたはsapplyを使用したいTHS場合

  • そのジョブに合ったapplyファミリー。しばしば私は個人的にlapplyまたはforループを使用して、特定の列を操作したり、インデックスを使用したい列をサブセット化して([, ])、applyに進みます。この問題への答えは、あなたが達成したいことを決めることに本当に沸きます。applyが最も適切なツールであると尋ね、そこでそこから進んでください。

    このblog postは、異なるapplyファミリの機能に関する優れたチュートリアルとして提供されます。

  • +1

    ブログの投稿は素晴らしいですが、私はそれが私の問題を解決しないと思います。データフレームに 'by 'を使用する必要がありますが、v1でグループ化するだけではなりません。 –

    0

    試してみてください。

    sapply(df, function(y) class(y["t2"])) 
    
    $v 
    [1] "integer" 
    
    $t 
    [1] "integer" 
    
    $t2 
    [1] "POSIXct" "POSIXt" 
    
    +1

    ありがとうございますが、データフレームの各行に自分の関数を適用する必要があります。その結果、元のデータフレームと同じ数の行が必要になります。 –

    関連する問題