我有一个包含一些日期字段的大约 200,000 行的 data.frame。我需要在数据框中添加一个新列,该列将具有与给定日期对应的会计年度值。一个财政年度跨越 2 年的部分时间。就我而言,是四月到三月。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)) somedate fy 1 2010-01-01 2009-10 2 2010-07-01 2009-10 警告消息:在 if (m < 4) { :条件的长度 > 1 和只使用第一个元素
在变异的情况下,输出是错误的。
简而言之,我试图在 ddply/transform 和 mutate 中使用用户定义的函数来处理大型数据集,但没有成功。请帮忙。
问候
ķ