You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于时间范围标记距NA值12小时内的温度数据行

问题描述

我有一个来自数据记录仪的温度数据tibble,希望使用dplyr::mutate()或其他{tidyverse}工具生成新列,标记出所有位于温度NA值12小时范围内的数据行。该时间序列存在完全缺失的间隙(并非仅记录为NA),因此基于行索引的方法无效,必须通过时间范围实现。

如何设置mutate命令,使距缺失温度12小时内的行返回TRUE,否则返回FALSE?

示例代码

library(tibble)
library(lubridate) # 需加载lubridate处理时间
temp.dat <- tibble(
  temperature = c(4,4.3,4.4,4.4,4.5,4.6,NA,NA,4.4,4.3),
  date.time = c(
    as_datetime("2012-09-29 18:00:00"),
    as_datetime("2012-09-30 00:00:00"), 
    as_datetime("2012-09-30 06:00:00"),
    as_datetime("2012-09-30 12:00:00"), 
    as_datetime("2012-09-30 18:00:00"),
    as_datetime("2012-10-01 00:00:00"), 
    as_datetime("2012-10-01 06:00:00"),
    as_datetime("2012-10-01 12:00:00"), 
    as_datetime("2012-10-01 18:00:00"),
    as_datetime("2012-10-02 00:00:00")
  )
)

示例数据

# A tibble: 10 × 2
   temperature date.time           
         <dbl> <dttm>              
 1         4   2012-09-29 18:00:00
 2         4.3 2012-09-30 00:00:00
 3         4.4 2012-09-30 06:00:00
 4         4.4 2012-09-30 12:00:00
 5         4.5 2012-09-30 18:00:00
 6         4.6 2012-10-01 00:00:00
 7        NA   2012-10-01 06:00:00
 8        NA   2012-10-01 12:00:00
 9         4.4 2012-10-01 18:00:00
10         4.3 2012-10-02 00:00:00

期望输出

# A tibble: 10 × 3
   temperature date.time           censor
         <dbl> <dttm>              <chr> 
 1         4   2012-09-29 18:00:00 F     
 2         4.3 2012-09-30 00:00:00 F     
 3         4.4 2012-09-30 06:00:00 F     
 4         4.4 2012-09-30 12:00:00 F     
 5         4.5 2012-09-30 18:00:00 T     
 6         4.6 2012-10-01 00:00:00 T     
 7        NA   2012-10-01 06:00:00 T     
 8        NA   2012-10-01 12:00:00 T     
 9         4.4 2012-10-01 18:00:00 T     
10         4.3 2012-10-02 00:00:00 T

尝试过的代码及问题

temp.dat%>%mutate(censor=if_else(NA %in% 
temp.dat[match(c(date.time,
        date.time-hours(12),
        date.time+hours(12)), temp.dat$date.time),]$temperature,"T","F"))

该代码会将所有行的censor值设为TRUE,原因是match()只能匹配数据中精确存在的时间点,而时间序列存在缺失间隙,大部分±12小时的时间点不在数据中,match()返回NA,导致判断逻辑失效。我们需要的是基于时间范围重叠的判断,而非精确时间匹配。


解决方案

利用lubridate的时间区间功能,结合dplyr的行级判断即可实现需求:

步骤1:提取所有温度为NA的时间点

library(dplyr)
library(lubridate)
library(purrr) # 用于map_lgl

# 获取所有NA对应的时间点
na_time_points <- temp.dat %>% 
  filter(is.na(temperature)) %>% 
  pull(date.time)

步骤2:生成标记列

通过map_lgl()对每行的时间点,判断其是否落在任何一个NA时间点的±12小时区间内:

result <- temp.dat %>%
  mutate(
    # 判断当前时间是否在任意NA时间的±12小时范围内
    censor = map_lgl(date.time, ~ any(.x %within% interval(na_time_points - hours(12), na_time_points + hours(12)))),
    # 转成期望的"T"/"F"字符格式
    censor = if_else(censor, "T", "F")
  )

print(result)

替代方案(使用rowwise)

如果不习惯purrr,也可以用rowwise()实现行级判断:

result <- temp.dat %>%
  rowwise() %>%
  mutate(
    censor = any(date.time %within% interval(na_time_points - hours(12), na_time_points + hours(12))),
    censor = if_else(censor, "T", "F")
  ) %>%
  ungroup()

输出验证

运行上述代码后,得到的结果与期望输出完全一致:

# A tibble: 10 × 3
   temperature date.time           censor
         <dbl> <dttm>              <chr> 
 1         4   2012-09-29 18:00:00 F     
 2         4.3 2012-09-30 00:00:00 F     
 3         4.4 2012-09-30 06:00:00 F     
 4         4.4 2012-09-30 12:00:00 F     
 5         4.5 2012-09-30 18:00:00 T     
 6         4.6 2012-10-01 00:00:00 T     
 7        NA   2012-10-01 06:00:00 T     
 8        NA   2012-10-01 12:00:00 T     
 9         4.4 2012-10-01 18:00:00 T     
10         4.3 2012-10-02 00:00:00 T

内容的提问来源于stack exchange,提问作者ghaines

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:02:07