0

いくつかの日付フィールドを持つ約 200,000 行の data.frame があります。指定された日付に対応する会計年度の値を持つデータ フレームに新しい列を追加する必要があります。会計年度は 2 年の一部にまたがります。私の場合は4月から3月です。2010 年 3 月 1 日の日付は 2009-10 年度に分類され、2010 年 7 月 1 日は 2010-11 年度に分類されます。この変換を行うスカラー関数をコーディングしました。これらの関数のコードは次のとおりです。

convMonthYearToFY = function(m, y){
  yn = y+1
  yp = y-1

  if (m < 4){
    fy = sprintf("%d-%02d", yp, y%%100)
  } else {
    fy = sprintf("%d-%02d", y, yn%%100)
  }
  return(fy)
}

convDateToFY = function(dt){
  y = 1900+as.POSIXlt(dt)$year
  m = 1+as.POSIXlt(dt)$mon
  return(convMonthYearToFY(m, y))
}

ddply/transform を使用して新しい列を作成しています

new_df = ddply(df, 1, transform, fy=convDateToFY(somedate))

次の動作が見られます。df には 200,000 行あるため、非常に低速です。次に、次の警告メッセージが表示されます

38: In if (m < 4) { ... :
  the condition has length > 1 and only the first element will be used
39: In if (m < 4) { ... :
  the condition has length > 1 and only the first element will be used
40: In if (m < 4) { ... :
  the condition has length > 1 and only the first element will be used
41: In if (m < 4) { ... :
  the condition has length > 1 and only the first element will be used

mutate を使用しようとしましたが、上記のように多くの警告メッセージも表示されます。どこで問題が発生している可能性があるのか​​ わからないため、これらの警告は面倒です。

警告なしでこの変換を達成できる最善かつ最速の方法は何ですか? サンプル データの場合、以下は 2 行のデータ フレームと ddply と mutate の動作です。

df = data.frame(somedate = as.Date(c("2010-01-01", "2010-07-01"), "%Y-%m-%d"))

> ddply(df, 1, transform, fy=convDateToFY(somedate))
    somedate      fy
1 2010-01-01 2009-10
2 2010-07-01 2010-11

出力はここで正しいです...

mutate(df, fy=convDateToFY(somedate)) somedate fy 1 2010-01-01 2009-10 2 2010-07-01 2009-10 警告メッセージ: In if (m < 4) { : 条件の長さ > 1 および最初の要素のみが使用されます

mutate の場合、出力は間違っています。

つまり、ddply/transform でユーザー定義関数を使用し、大規模なデータセットを変更しようとしていますが、成功していません。助けてください。

よろしく

K

4

1 に答える 1