0

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

safe.ifelse <- function(cond, yes, no) 结构(ifelse(cond, yes, no), class = class(yes))

图书馆(润滑)

df <- data.frame(i_date=mdy("9/1/2011") + 月(seq(0,31)), t_date=mdy("2/1/2012")) 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 > max(i_date),则 i_date 将与 t_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
4

2 回答 2

0

我认为使用repwith没有多大ifelse意义,因为ifelse对每一行都进行操作。我假设您开始替换的那些,您将继续为 data.frame 的其余部分这样做。假设您调用了上面的 data.framex并且前两列是正确的日期类,那么我可能会这样做

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))))

它并不完全优雅,但也许有人会有更好的解决方案。

于 2014-06-16T04:27:33.653 回答
0

这应该适用于i_date以一个月为增量递增的有序数据,如上述数据。我将使用lubridate包来更容易地操作日期。

我将上面的数据复制为 dataframe 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年数添加到 t_date 。如果不在范围内,则设置为负数。ri_datet_datert_datei_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
于 2014-06-16T10:02:50.417 回答