R语言mutate新增列:判断后续自定义行数内是否存在低于阈值的值
R数据框新增列判断滑动窗口内是否出现零下气温
需求规则
- 数据框包含3个基础列:
date为日期列,temp为当天气温列,duration为流程从当日启动后持续的天数 - 新增列取值规则:逐行遍历,以当前行为起点,取连续
duration个行(包含当前行)组成窗口,窗口内任意temp值小于0时,当前行新列取值为TRUE,否则为FALSE - 逻辑校验:示例数据中首行
duration为12,覆盖第1到12行,第10行temp为负值,因此首行新列值为TRUE;第3行duration为1,仅覆盖第3行,该行temp大于0,因此取值为FALSE
测试示例数据
set.seed(1) df = data.frame(date = seq(as.Date("2020-01-01"),as.Date("2020-04-09"), by=1), temp = runif(100,min=-2,max=30), duration = sample.int(20,100,replace=TRUE)) # 查看前10行数据 head(df, n=10)
控制台输出前10行:
date temp duration 1 2020-01-01 6.49627722 12 2 2020-01-02 9.90796479 16 3 2020-01-03 16.33130763 1 4 2020-01-04 27.06264928 13 5 2020-01-05 4.45382179 6 6 2020-01-06 26.74846992 17 7 2020-01-07 28.22960860 9 8 2020-01-08 19.14552936 7 9 2020-01-09 18.13164940 19 10 2020-01-10 -0.02283935 18
正确实现代码
purrr::map_lgl 版本
注意需要处理窗口边界,避免结束行超出数据框总行数:
library(purrr) df$has_subzero <- map_lgl(seq_len(nrow(df)), ~{ end <- min(.x + df$duration[.x] - 1, nrow(df)) any(df$temp[.x:end] < 0) })
运行后查看前10行结果,完全符合预期:
date temp duration has_subzero 1 2020-01-01 6.49627722 12 TRUE 2 2020-01-02 9.90796479 16 TRUE 3 2020-01-03 16.33130763 1 FALSE 4 2020-01-04 27.06264928 13 TRUE 5 2020-01-05 4.45382179 6 TRUE 6 2020-01-06 26.74846992 17 TRUE 7 2020-01-07 28.22960860 9 TRUE 8 2020-01-08 19.14552936 7 TRUE 9 2020-01-09 18.13164940 19 TRUE 10 2020-01-10 -0.02283935 18 TRUE
之前map_lgl运行结果错误,通常是两个原因:一是窗口长度计算错误,比如写成
.x:(.x + df$duration[.x])多取了1行;二是没有做边界截断,当窗口结束位置超过数据框总行数时会出现索引越界,返回错误值。
基础R版本(无需加载额外包)
df$has_subzero <- vapply(seq_len(nrow(df)), function(i) { end <- min(i + df$duration[i] - 1, nrow(df)) any(df$temp[i:end] < 0) }, logical(1))
内容的提问来源于stack exchange,提问作者StvnWgnr
相关产品推荐
相关产品推荐

