我有一个数据框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()
函数在这里似乎不适用。我的一个想法是使用zoo
将rollapply
列转换为嵌套列,然后使用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)))
答案 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)