满足条件时复制序列

时间:2014-06-16 02:40:12

标签: r sequence replicate

要生成下面的输出,我使用以下代码:

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

2 个答案:

答案 0 :(得分:0)

我认为将repifelse一起使用非常有意义,因为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