在R中实现逻辑值回溯请求——附结构化销售数据示例
R语言实现逻辑值回溯操作方案
看起来你需要按城市分组,对每个标记为指标=1的行,回溯找到同城市中最近的指标=0的记录对吧?我给你准备了两种常用的实现方案,分别用dplyr(适合轻量数据、代码易读)和data.table(适合大数据、效率更高),先从构造测试数据开始:
第一步:构造示例数据
先把你提供的结构化数据转成可直接运行的R数据框(补全了截断的部分):
library(tibble) df <- tibble( 序号 = 1:12, 日期 = c("2017/1/1", "2017/1/31", "2017/3/2", "2017/4/1", "2017/5/1", "2017/5/31", "2017/6/30", "2017/1/1", "2017/1/31", "2017/3/2", "2017/4/1", "2017/5/1"), 城市 = rep(c("纽约", "巴黎"), each=7, length.out=12), 销售额 = c(2795, 4248, 1330, 3535, 4330, 3360, 2238, 1451, 2339, 2029, 1850, 2800), 差值 = c(0, 1453, -2918, 2205, 795, -970, -1122, 0, 888, -310, -179, 950), 指标 = c(0,0,1,0,0,1,1,0,0,1,1,0) )
方案一:用dplyr实现(易读性优先)
核心思路是按城市分组后,将每个指标=0的序号向下填充,覆盖后续的指标=1行,这样就能快速关联到最近的0的记录:
library(dplyr) result_df <- df %>% # 按城市分组处理 group_by(城市) %>% # 标记所有指标为0的行的序号,其余行设为NA mutate(最近0的序号 = ifelse(指标 == 0, 序号, NA)) %>% # 向下填充NA值,让每个1的行继承最近的0的序号 fill(最近0的序号, .direction = "down") %>% # 关联原表,获取最近0的日期、销售额等信息(如果不需要可以省略这步) left_join(df %>% select(序号, 最近0日期=日期, 最近0销售额=销售额), by = c("最近0的序号" = "序号")) %>% # 取消分组 ungroup() # 查看结果 print(result_df)
运行后你会看到,每个指标=1的行都带上了同城市里上一个0的序号、日期和销售额,比如纽约第3行(指标=1)对应的最近0是第2行,第6、7行的指标=1对应的最近0是第5行。
方案二:用data.table实现(效率优先)
如果你的数据量很大(比如百万级以上),推荐用data.table的滚动连接,速度会快很多:
library(data.table) # 转成data.table格式 dt <- as.data.table(df) # 先提取所有指标为0的记录,作为回溯的参照表 dt_0 <- dt[指标 == 0, .(城市, 序号_0=序号, 日期_0=日期, 销售额_0=销售额)] # 按城市分组,用滚动连接找到每个行对应的最近0的记录 result_dt <- dt[dt_0, on = .(城市, 序号 >= 序号_0), roll = TRUE, .(序号, 日期, 城市, 销售额, 差值, 指标, 最近0的序号=i.序号_0, 最近0日期=i.日期_0, 最近0销售额=i.销售额_0)] # 查看结果 print(result_dt)
这里的roll=TRUE参数会在每个城市组内,为当前行找到小于等于当前序号的最大的0的序号,也就是最近的那个0的记录,完美匹配你的回溯需求。
自定义调整说明
如果你的需求是其他类型的回溯(比如回溯到上一个0之后的所有记录,或者计算1与最近0的差值),只需要在上述代码基础上修改即可:
- 比如要计算当前销售额与最近0的销售额的差值:可以加一行
mutate(销售额差值 = 销售额 - 最近0销售额) - 比如要筛选出所有指标=1的行:可以在最后加
filter(指标 == 1)
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

