要生成下面的输出,我使用以下代码:
safe.ifelse< - function(cond,yes,no)structure(ifelse(cond,yes,no),class = class(yes))
library(lubridate)
df< - data.frame(i_date = mdy(" 9/1/20")+月(seq(0,31)),t_date = mdy(" 2/1 / 2012&#34)) r< -seq(1:nrow(df))
r< - (r - (df $ i_date == df $ t_date))%/%12
df $ r_date< - as.Date(safe.ifelse(r< 0,df $ i_date,df $ t_date + years(r)),origin =" 1970-01-01")
有充分的理由,如果我将t_date设置为超出最大的i_date,则会出错。有谁知道避免这个错误的方法?因此,不是找到i_date和t_date匹配的位置,复制t_date 12次并添加一年,再次复制12次等,我只是将i_date级联到r_date的末尾,其中数据帧的所有三列都是长度相同。因此,在我所指的情况下,如果t_date是>,则i_date将匹配t_date。 max(i_date)否则我们会做我们在下面看到的。谢谢!
i_date t_date r_date
9/1/2011 2/1/2012 9/1/2011
10/1/2011 2/1/2012 10/1/2011
11/1/2011 2/1/2012 11/1/2011
12/1/2011 2/1/2012 12/1/2011
1/1/2012 2/1/2012 1/1/2012
2/1/2012 2/1/2012 2/1/2012
3/1/2012 2/1/2012 2/1/2012
4/1/2012 2/1/2012 2/1/2012
5/1/2012 2/1/2012 2/1/2012
6/1/2012 2/1/2012 2/1/2012
7/1/2012 2/1/2012 2/1/2012
8/1/2012 2/1/2012 2/1/2012
9/1/2012 2/1/2012 2/1/2012
10/1/2012 2/1/2012 2/1/2012
11/1/2012 2/1/2012 2/1/2012
12/1/2012 2/1/2012 2/1/2012
1/1/2013 2/1/2012 2/1/2012
2/1/2013 2/1/2012 2/1/2013
3/1/2013 2/1/2012 2/1/2013
4/1/2013 2/1/2012 2/1/2013
5/1/2013 2/1/2012 2/1/2013
6/1/2013 2/1/2012 2/1/2013
7/1/2013 2/1/2012 2/1/2013
8/1/2013 2/1/2012 2/1/2013
9/1/2013 2/1/2012 2/1/2013
10/1/2013 2/1/2012 2/1/2013
11/1/2013 2/1/2012 2/1/2013
12/1/2013 2/1/2012 2/1/2013
1/1/2014 2/1/2012 2/1/2013
2/1/2014 2/1/2012 2/1/2014
3/1/2014 2/1/2012 2/1/2014
4/1/2014 2/1/2012 2/1/2014
答案 0 :(得分:0)
我认为将rep
与ifelse
一起使用非常有意义,因为ifelse
会对每一行进行操作。我假设您开始替换,您将继续为其余的data.frame执行此操作。假设您上面的data.frame被称为x
并且前两列是正确的日期类,那么我可能会这样做
ww <- seq_along(x$i_date)-which(x$i_date == x$t_date)
通过它与值相等的偏移来标识每一行。然后我们可以在数据透视日期上添加年份来计算其余行的值
pvdate <- as.Date(
paste(as.numeric(strftime(x$t_date[ww==0], "%Y"))+0:max(floor(ww/12)),
strftime(x$t_date[ww==0], "%m-%d"), sep="-")
)
这是一个混乱的日期算术,但它完成了工作。现在我只是将未替换的行与替换的行组合起来
x$r_date<-c(x$i_date[ww<=0], rep(pvdate, table(floor(ww[ww>0]/12))))
这不是很优雅,但也许有人会有更好的解决方案。
答案 1 :(得分:0)
这适用于有序数据,其中i_date
以一个月为单位递增,如上面的数据所示。我将使用lubridate
包来更轻松地操作日期。
我将您的数据复制为数据框df
。
library(lubridate)
td <- mdy("2/1/2012")
df <- data.frame(i_date=mdy("9/1/2011") + months(seq(0,31)),
t_date=td)
我在变量r
中创建临时索引,以指示要添加多少年(实质上是12个月)。然后,只需将r
年数从r
不为负值(即i_date
不再小于t_date
)添加到t_date。如果r
不在t_date
范围内,请将i_date
设为否定。
if (td %in% df$i_date) {
r <- (seq(1:nrow(df)) - which(df$i_date == df$t_date)) %/% 12
} else { r <- rep(-1, nrow(df)) }
df$r_date <- as.POSIXct(ifelse(r<0, df$i_date,
df$t_date + years(r)), origin = "1970-01-01")
我的结果如下。
i_date t_date r_date
1 2011-09-01 2012-02-01 2011-09-01 08:00:00
2 2011-10-01 2012-02-01 2011-10-01 08:00:00
3 2011-11-01 2012-02-01 2011-11-01 08:00:00
4 2011-12-01 2012-02-01 2011-12-01 08:00:00
5 2012-01-01 2012-02-01 2012-01-01 08:00:00
6 2012-02-01 2012-02-01 2012-02-01 08:00:00
7 2012-03-01 2012-02-01 2012-02-01 08:00:00
8 2012-04-01 2012-02-01 2012-02-01 08:00:00
9 2012-05-01 2012-02-01 2012-02-01 08:00:00
10 2012-06-01 2012-02-01 2012-02-01 08:00:00
11 2012-07-01 2012-02-01 2012-02-01 08:00:00
12 2012-08-01 2012-02-01 2012-02-01 08:00:00
13 2012-09-01 2012-02-01 2012-02-01 08:00:00
14 2012-10-01 2012-02-01 2012-02-01 08:00:00
15 2012-11-01 2012-02-01 2012-02-01 08:00:00
16 2012-12-01 2012-02-01 2012-02-01 08:00:00
17 2013-01-01 2012-02-01 2012-02-01 08:00:00
18 2013-02-01 2012-02-01 2013-02-01 08:00:00
19 2013-03-01 2012-02-01 2013-02-01 08:00:00
20 2013-04-01 2012-02-01 2013-02-01 08:00:00
21 2013-05-01 2012-02-01 2013-02-01 08:00:00
22 2013-06-01 2012-02-01 2013-02-01 08:00:00
23 2013-07-01 2012-02-01 2013-02-01 08:00:00
24 2013-08-01 2012-02-01 2013-02-01 08:00:00
25 2013-09-01 2012-02-01 2013-02-01 08:00:00
26 2013-10-01 2012-02-01 2013-02-01 08:00:00
27 2013-11-01 2012-02-01 2013-02-01 08:00:00
28 2013-12-01 2012-02-01 2013-02-01 08:00:00
29 2014-01-01 2012-02-01 2013-02-01 08:00:00
30 2014-02-01 2012-02-01 2014-02-01 08:00:00
31 2014-03-01 2012-02-01 2014-02-01 08:00:00
32 2014-04-01 2012-02-01 2014-02-01 08:00:00