在具有每周频率的xts对象中滞后1年。

huangapple go评论75阅读模式
英文:

Lagging 1 year in xts object with weekly frequency

问题

我正在尝试将一个xts数据集滞后1年。数据的频率是每周的,我目前正在使用lag.xts函数,如下所示:

lag.xts(my_data, 52)

问题是并非所有年份都有52周(有些有53周)。有没有办法可以考虑这一点呢?

英文:

I am trying to lag an xts dataset by 1 year. The data has weekly frequency, and I am currently using lag.xts function like so:

lag.xts(my_data, 52)

The problem is not all years have 52 weeks (some have 53). Is there a way I can take this into account somehow?

答案1

得分: 3

这是一个将数据转换为 tibble 然后再转换回 xts 的替代解决方案。

辅助函数将 xts 转换为 tibble。

xts_as_tibble <- function(x, name = "time", value = "value", group = "group"){
  time <- attr(x, "index")
  if ("POSIXt" %in% attr(time, "tclass")){
    if (!is.null(attr(time, "tzone"))){
      time <- lubridate::as_datetime(time,
                                     tz = attr(time, "tzone"))
    } else {
      time <- lubridate::as_datetime(time)
    }
  } else if ("Date" %in% attr(time, "tclass")){
    time <- lubridate::as_date(time)
  } else {
    time <- as.numeric(time)
  }
  ncol <- ncol(x)
  groups <- rep(colnames(x), each = length(time))
  if (is.null(groups)){
    groups <- rep(seq_len(ncol), each = length(time))
  }
  time <- rep(time, times = ncol)
  dplyr::tibble(!!group := groups,
                !!name := time,
                !!value := as.vector(x))
}

计算

library(tidyverse)
res <- my_data %>%
  xts_as_tibble() %>%
  pivot_wider(names_from = group, values_from = value) %>%
  mutate(across(-time, ~ if_else(time >= min(time) + years(1), .x, NA)))
my_data_lag <- xts(select(res, -time), order.by = res$time)
英文:

Here's an alternative solution that converts to tibble and then back to xts.

Helper to convert xts to tibble.

xts_as_tibble &lt;- function(x, name = &quot;time&quot;, value = &quot;value&quot;, group = &quot;group&quot;){
  time &lt;- attr(x, &quot;index&quot;)
  if (&quot;POSIXt&quot; %in% attr(time, &quot;tclass&quot;)){
    if (!is.null(attr(time, &quot;tzone&quot;))){
      time &lt;- lubridate::as_datetime(time,
                                     tz = attr(time, &quot;tzone&quot;))
    } else {
      time &lt;- lubridate::as_datetime(time)
    }
  } else if (&quot;Date&quot; %in% attr(time, &quot;tclass&quot;)){
    time &lt;- lubridate::as_date(time)
  } else {
    time &lt;- as.numeric(time)
  }
  ncol &lt;- ncol(x)
  groups &lt;- rep(colnames(x), each = length(time))
  if (is.null(groups)){
    groups &lt;- rep(seq_len(ncol), each = length(time))
  }
  time &lt;- rep(time, times = ncol)
  dplyr::tibble(!!group := groups,
                !!name := time,
                !!value := as.vector(x))
}

Calculation

library(tidyverse)
res &lt;- my_data %&gt;%
  xts_as_tibble() %&gt;%
  pivot_wider(names_from = group, values_from = value) %&gt;%
  mutate(across(-time, ~ if_else(time &gt;= min(time) + years(1), .x, NA)))
my_data_lag &lt;- xts(select(res, -time), order.by = res$time)

答案2

得分: 1

这段代码的目的是找到距离指定日期最近的日期,减去一年。以下是代码的翻译部分:

我假设你想找到距离指定日期最近的日期,减去一年?

这段代码实现了相同的功能,但适用于一个数据框架的值:

library(tidyverse)

data <- tibble(x = rnorm(100), 
               dates = seq(as.Date("2015-12-27"), length = 100, by = "weeks"))

find_closest_day <- function(t) {
    ty = t - years(1)
    t52 = abs((t - weeks(52)) - ty)
    t53 = abs((t - weeks(53)) - ty)
    if (t52 < t53) {
        return(t - weeks(52))
    } else {
        return(t - weeks(53))
    }
}
find_closest_day<- Vectorize(find_closest_day)

data %>% 
  mutate(lagged_monday = as.Date(find_closest_day(dates))) %>%
  left_join(data, by = c("lagged_monday" = "dates"))

       x.x dates      lagged_monday   x.y
     <dbl> <date>     <date>        <dbl>
 1 -0.0768 2015-12-27 2014-12-28       NA
 2 -0.711  2016-01-03 2015-01-04       NA
 3 -1.94   2016-01-10 2015-01-11       NA
 4  0.584  2016-01-17 2015-01-18       NA
 5 -0.266  2016-01-24 2015-01-25       NA
 6 -1.04   2016-01-31 2015-02-01       NA
 7 -0.954  2016-02-07 2015-02-08       NA
 8 -0.809  2016-02-14 2015-02-15       NA
 9  0.458  2016-02-21 2015-02-22       NA
10  0.367  2016-02-28 2015-03-01       NA
# ℹ 90 more rows

希望这对你有帮助。

英文:

I'm assuming you want to find the date which is closest to the specified date, minus a year?

This does the equivalent, but for a dataframe of values:

library(tidyverse)

data &lt;- tibble(x = rnorm(100), 
               dates = seq(as.Date(&quot;2015-12-27&quot;), length = 100, by = &quot;weeks&quot;))

find_closest_day &lt;- function(t) {
    ty = t - years(1)
    t52 = abs((t - weeks(52)) - ty)
    t53 = abs((t - weeks(53)) - ty)
    if (t52 &lt; t53) {
        return(t - weeks(52))
    } else {
        return(t - weeks(53))
    }
}
find_closest_day&lt;- Vectorize(find_closest_day)

data %&gt;% 
  mutate(lagged_monday = as.Date(find_closest_day(dates))) %&gt;%
  left_join(data, by = c(&quot;lagged_monday&quot; = &quot;dates&quot;))

       x.x dates      lagged_monday   x.y
     &lt;dbl&gt; &lt;date&gt;     &lt;date&gt;        &lt;dbl&gt;
 1 -0.0768 2015-12-27 2014-12-28       NA
 2 -0.711  2016-01-03 2015-01-04       NA
 3 -1.94   2016-01-10 2015-01-11       NA
 4  0.584  2016-01-17 2015-01-18       NA
 5 -0.266  2016-01-24 2015-01-25       NA
 6 -1.04   2016-01-31 2015-02-01       NA
 7 -0.954  2016-02-07 2015-02-08       NA
 8 -0.809  2016-02-14 2015-02-15       NA
 9  0.458  2016-02-21 2015-02-22       NA
10  0.367  2016-02-28 2015-03-01       NA
# ℹ 90 more rows

huangapple
  • 本文由 发表于 2023年7月10日 16:06:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76651828.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定