【问题标题】:Replicate a sequence when a condition is met满足条件时复制序列
【发布时间】:2014-06-16 02:40:12
【问题描述】:

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

safe.ifelse

图书馆(润滑)

df

r

df$r_date

如果我将 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

【问题讨论】:

  • 很高兴有想要的输出,但输入是什么?
  • 输入是前两列。
  • 理想情况下,我会使用数据框中的前 2 列来生成第 3 列。

标签: r sequence replicate


【解决方案1】:

这应该适用于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 不是负数的点(即i_date 不再小于t_date)将r 年数添加到t_date。如果t_date 不在i_date 的范围内,则将r 设置为负数。

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

【讨论】:

  • 这正是我想要的,但是,当我尝试使用您的代码时,我收到以下消息:错误:在您拥有 r
  • 我一直在尝试用不同的值在上面的代码中初始化 r,但我似乎无法以你在输出中的方式得到任何东西。
  • 抱歉我错过了一行。 r 起始值应该是行数的序列: r
  • 我一回到家就试一试,非常感谢您的帮助,非常感谢!
  • 运行该代码我得到每个月的最后一天,例如:2011-08-31 19:00:00 2011-09-30 19:00:00 等
【解决方案2】:

我认为将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))))

这不是很优雅,但也许有人会有更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2020-03-05
    • 2014-12-01
    • 2021-05-12
    • 1970-01-01
    • 2017-10-22
    相关资源
    最近更新 更多