我有一个大约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中使用用户定义的函数来获取大数据集,但没有成功。请帮忙。
问候
ķ
答案 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))