我想在我的数据框中添加一个新列,该列用于对具有以下条件的连续天数进行计数:如果“返回”值大于3,则对连续天数进行计数。
这是我的数据集:
df <- tibble(
date = lubridate::today() +0:9,
return= c(1,2.5,2,3,5,6.5,1,9,3,2))
我的数据框应如下所示:
date return Consec_days
<date> <dbl> <dbl>
1 2019-02-20 1 NA
2 2019-02-21 2.5 NA
3 2019-02-22 2 NA
4 2019-02-23 3 NA
5 2019-02-24 5 1
6 2019-02-25 6.5 2
7 2019-02-26 1 NA
8 2019-02-27 9 NA
9 2019-02-28 3 1
10 2019-03-01 2 NA
如果不满足条件,请给我“ NA”或“ 0”
我已经尝试过:
df$Consec_Days <- with(df, ave(return, data.table::rleid(return > 3),
FUN = function(x) ifelse(return > 3, seq_along(x), 0L)))
但是它不起作用。有人可以帮我吗?
答案 0 :(得分:2)
使用底数R ave
和data.table::rleid
的选项
library(data.table)
df$Consec_days <- with(df, (return > 3) * ave(return, rleid(return > 3), FUN = seq_along))
# date return Consec_days
# <date> <dbl> <dbl>
# 1 2019-02-20 1 0
# 2 2019-02-21 2.5 0
# 3 2019-02-22 2 0
# 4 2019-02-23 3 0
# 5 2019-02-24 5 1
# 6 2019-02-25 6.5 2
# 7 2019-02-26 1 0
# 8 2019-02-27 9 1
# 9 2019-02-28 3 0
#10 2019-03-01 2 0
使用rleid(return > 3)
创建分组,然后使用seq_along
并为每个分组创建观察顺序
with(df, ave(return, rleid(return > 3), FUN = seq_along))
# [1] 1 2 3 4 1 2 1 1 1 2
我们将其乘以(return > 3)
,以保留大于3的观测值,其余的全部变为0。
将其翻译成dplyr
我们可以做到
library(dplyr)
df %>%
group_by(group = rleid(return > 3)) %>%
mutate(consec_days = (return > 3) * row_number()) %>%
ungroup() %>%
select(-group)
答案 1 :(得分:1)
一种dplyr
可能是:
df %>%
group_by(return_rleid = {return_rleid = rle(return > 3); rep(seq_along(return_rleid$lengths), return_rleid$lengths)}) %>%
mutate(Consec_days = ifelse(return <= 3, NA, seq_along(return_rleid))) %>%
ungroup() %>%
select(-return_rleid)
date return Consec_days
<date> <dbl> <int>
1 2019-02-20 1.00 NA
2 2019-02-21 2.50 NA
3 2019-02-22 2.00 NA
4 2019-02-23 3.00 NA
5 2019-02-24 5.00 1
6 2019-02-25 6.50 2
7 2019-02-26 1.00 NA
8 2019-02-27 9.00 1
9 2019-02-28 3.00 NA
10 2019-03-01 2.00 NA
首先,它按照游程长度组ID进行分组。其次,如果“ return”大于3,它将在游程长度组ID周围创建一个序列,否则进行分配。最后,它取消分组并删除冗余变量。
相同,但由gl()
生成序列:
df %>%
group_by(return_rleid = {return_rleid = rle(return > 3); rep(seq_along(return_rleid$lengths), return_rleid$lengths)}) %>%
mutate(Consec_days = ifelse(return <= 3, NA, gl(length(return_rleid), 1))) %>%
ungroup() %>%
select(-return_rleid)