如何根据条件选择R数据框中的连续行?
Posted
技术标签:
【中文标题】如何根据条件选择R数据框中的连续行?【英文标题】:How to select continuous rows in R data frame based on conditions? 【发布时间】:2018-10-25 15:45:02 【问题描述】:我有一个数据框 df,它有 date 、 group 和 gap days 列。我想为一个组选择从最新日期(最大日期)开始间隔天数连续为 1 的所有行。如果 gap days 不等于 1 ,那么我们会忽略行,直到 gap days 不等于 1 为止。出于可重现的目的,我创建了当前的 df 和预期的 df...
df<-data.frame(Date=c("2018-10-15","2018-10-16","2018-10-17",
"2018-10-14","2018-10-15","2018-10-16","2018-10-18","2018-10-19",
"2018-10-18","2018-10-21","2018-10-23","2018-10-24","2018-10-27","2018-10-28"),Group=c("a","a","a","b","b","b","b","b","c","c","c","c","c","c"),Gap_Days=c(1,1,1,1,1,2,1,1,3,2,1,3,1,1))
df_expected<-data.frame(Date=c("2018-10-15","2018-10-16","2018-10-17","2018-10-18","2018-10-19","2018-10-27","2018-10-28"),Group=c("a","a","a", "b","b","c","c"),Gap_Days=c(1,1,1,1,1,1,1))
【问题讨论】:
df[rev(cumall(rev(df$Gap_Days == 1))),]
感谢您的评论,尽管它不符合我的要求...如果我按条件在组中应用上述代码...那么它只会显示所有内容为 1 的那些组...。如果只有一个条目,则不显示
根据您提供的测试数据,它完全符合您的预期输出。如果您还有其他条件,建议您更新测试数据以捕获这些条件。
谢谢....我会更新我的问题
这就是“单元测试”变得有价值的地方:找到错误,编写测试以突出显示该错误,然后修复错误。
【参考方案1】:
我的第一条评论与现在有效的唯一区别是对问题进行了分组。
基础R:
do.call("rbind", by(df, df$Group, FUN=function(d) d[rev(cumall(rev(d$Gap_Days == 1))),]))
# Date Group Gap_Days
# a.1 2018-10-15 a 1
# a.2 2018-10-16 a 1
# a.3 2018-10-17 a 1
# b.7 2018-10-18 b 1
# b.8 2018-10-19 b 1
# c.13 2018-10-27 c 1
# c.14 2018-10-28 c 1
Tidyverse:
df %>%
group_by(Group) %>%
filter(rev(cumall(rev(Gap_Days == 1)))) %>%
ungroup()
# # A tibble: 7 x 3
# Date Group Gap_Days
# <fct> <fct> <dbl>
# 1 2018-10-15 a 1
# 2 2018-10-16 a 1
# 3 2018-10-17 a 1
# 4 2018-10-18 b 1
# 5 2018-10-19 b 1
# 6 2018-10-27 c 1
# 7 2018-10-28 c 1
【讨论】:
【参考方案2】:这是tidyverse
的一种方法
library(dplyr)
library(data.table)
df %>%
group_by(grp = rleid(Gap_Days),
ind = any(Date == max(.data$Date))) %>%
ungroup %>%
filter(grp == max(grp) & ind) %>%
select(-ind, -grp)
# A tibble: 3 x 2
# Date Gap_Days
# <date> <dbl>
#1 2018-10-19 1
#2 2018-10-20 1
#3 2018-10-21 1
如果 'Date' 列已经排序,那么我们只需要检查 'Gap_Days 中的 1 即可
i1 <- inverse.rle(within.list(rle(df$Gap_Days == 1),
values[lengths < max(lengths) & values] <- FALSE))
df[i1,, drop = FALSE]
【讨论】:
以上是关于如何根据条件选择R数据框中的连续行?的主要内容,如果未能解决你的问题,请参考以下文章