在ddply / transform中使用用户定义的函数时获取警告,对大型数据集进行mutate

时间:2013-08-31 15:17:51

标签: r plyr

我有一个大约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,它也给了我很多警告信息,如上所述。这些警告很麻烦,因为我无法看出问题出在哪里。

在没有任何警告的情况下,我能够实现这一转变的最佳和最快方式是什么?对于样本数据,下面是两行的数据框以及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))       某个日期   1 2010-01-01 2009-10   2 2010-07-01 2009-10   警告信息:   在if(m <4){:     条件的长度> 1,只使用第一个元素

如果是mutate,则输出为WRONG。

简而言之,我试图在ddply / transform和mutate中使用用户定义的函数来获取大数据集,但没有成功。请帮忙。

问候

ķ

1 个答案:

答案 0 :(得分:0)

未经测试

mydata$yn<- mydata$y+1
mydata$yp<- mydata$y-1
mydata$fy<-with(mydata,ifelse (m < 4), sprintf("%d-%02d", yp, y%%100),sprintf("%d-%02d", y, yn%%100))