R:在列表列上使用rollapply

时间:2018-09-14 07:16:42

标签: r zoo purrr

我有一个数据框df,其中有一个dates列和一个values列,并想计算过去{{1} values中每个日期的}天。问题在于日期不是唯一地出现,并且没有不同的(随机)基数。例如

n

我可以编写一个for循环来解决此问题,但这很慢:

dates

我尝试了library(lubridate) library(tidyverse) library(zoo) n <- 3 dates_v <- seq(as_date("2018-09-01"), as_date("2018-09-14"), by = "days") df <- data.frame(dates = rep(dates_v,c(3, 2, 1, 4, 1, 5, 1, 3, 3, 2, 5, 3, 4, 3)), values = rep(seq(1,5),8)) 软件包,但是由于窗口大小的变化,df2 <- list() for (k in dates_v[n:length(dates_v)]) { k <- as_date(k) df2 <- c(df2, df %>% filter(dates >= k %m-% days(n-1) & dates <= k) %>% mutate(dates = k) %>% group_by(dates) %>% summarise(values = quantile(values, 0.05)) %>% list()) } df2 <- df2 %>% bind_rows() 函数在这里似乎不适用。我的一个想法是使用zoorollapply列转换为嵌套列,然后使用values滚动连接嵌套列的条目

purrr::nest

但是没有解决。我在做错什么吗?还是rollapply根本无法使用列表列?

编辑:

在我的用例中,更现实的示例是格式为

的数据框
df2 <- df %>%
  group_by(dates) %>%
  nest() %>%
  mutate(data = map(data, unlist))

df2$data <- rollapply(df2$data, width = n, c, align = "right")

df2 %>% 
  mutate(data = map(data, ~quantile(., 0.05)))

2 个答案:

答案 0 :(得分:2)

您可以像这样使用char *而不是循环:

pubmsg.payload = (char *)(&i);

要将其放入data.frame中,您可以执行以下操作:

sapply

答案 1 :(得分:2)

通过指定宽度向量rollapply(每个元素一个),可以将

w用于不同的宽度。 r给出从第一个dates-2行到当前行的所有行的分位数,最后一行代码删除日期不是该日期最后一次出现的行,并删除value列。

w <- seq_along(df$dates) - match(df$dates - 2, df$dates, nomatch = 0)
r <- transform(df, `5%` = rollapplyr(values, w, quantile, 0.05), 
  check.names = FALSE)

r[!duplicated(df$dates, fromLast = TRUE), -2]

给予:

        dates   5%
3  2018-09-01 1.10
5  2018-09-02 1.20
6  2018-09-03 1.20
10 2018-09-04 1.25
11 2018-09-05 1.20
16 2018-09-06 1.00
17 2018-09-07 1.25
20 2018-09-08 1.35
23 2018-09-09 1.25
25 2018-09-10 1.30
30 2018-09-11 1.40
33 2018-09-12 1.00
37 2018-09-13 1.00
40 2018-09-14 1.40

或使用管道并从上方使用w

df %>%
   mutate(`5%` = rollapplyr(.$values, w, quantile, 0.05)) %>%
   filter(!duplicated(.$dates, fromLast = TRUE)) %>%
   select(-values)