如何为成对观测Data Frame生成时间先后二进制标识变量
解决方案:为成对观测生成二进制标识变量
需求回顾
我们需要为包含成对观测的Data Frame生成一个二进制标识变量,规则如下:
- 成对观测中时间戳更早的赋值为1,另一个为0
- 若仅一个时间戳缺失,非缺失的观测赋值为1
- 若两个时间戳均缺失,该组两个观测的标识均赋值为NA
示例数据
你提供的示例数据生成代码:
# Create a vector of pair IDs pair_ids <- c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5) # Create a vector of observation IDs obs_ids <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) # Create a vector of date/time values, including some missing values date_times <- c("2023-03-27 10:00:00", "2023-03-27 10:15:00", "2023-03-27 11:00:00", "2023-03-27 11:15:00", "2023-03-27 12:00:00", NA, NA, "2023-03-27 13:00:00", NA, NA) # Create a data frame with the three columns df <- data.frame(pair_id = pair_ids, obs_id = obs_ids, date_time = as.POSIXct(date_times))
方案一:使用dplyr(推荐)
dplyr的分组操作适合处理这类按组逻辑计算的场景,代码可读性高且效率优异,适配大量成对数据:
library(dplyr) df_processed <- df %>% group_by(pair_id) %>% mutate( # 统计每组时间戳缺失数量 na_count = sum(is.na(date_time)), # 按规则生成标识变量 flag = case_when( na_count == 2 ~ NA_integer_, na_count == 1 ~ as.integer(!is.na(date_time)), TRUE ~ as.integer(date_time == min(date_time, na.rm = TRUE)) ) ) %>% ungroup() %>% select(-na_count) # 移除中间计算列
代码逻辑说明
- 按
pair_id分组:确保每组仅包含一对观测 - 统计缺失数:
na_count用于判断当前组的缺失情况 - 多条件分支:
- 组内两个时间戳都缺失时,
flag赋值为NA - 仅一个缺失时,非缺失观测赋值1,缺失的赋值0
- 无缺失时,将时间戳等于组内最小值(最早时间)的观测赋值1,其余为0
- 组内两个时间戳都缺失时,
方案二:Base R实现
如果不想加载额外包,可使用Base R的ave函数实现相同逻辑:
# 计算每组缺失数量 df$na_count <- ave(is.na(df$date_time), df$pair_id, FUN = sum) # 生成标识变量 df$flag <- with(df, ifelse(na_count == 2, NA_integer_, ifelse(na_count == 1, as.integer(!is.na(date_time)), as.integer(date_time == ave(date_time, pair_id, FUN = function(x) min(x, na.rm = TRUE))) ) ) ) # 移除中间计算列 df$na_count <- NULL
处理后结果
运行上述任意方案后,得到的Data Frame如下:
| pair_id | obs_id | date_time | flag |
|---|---|---|---|
| 1 | 1 | 2023-03-27 10:00:00 | 1 |
| 1 | 2 | 2023-03-27 10:15:00 | 0 |
| 2 | 3 | 2023-03-27 11:00:00 | 1 |
| 2 | 4 | 2023-03-27 11:15:00 | 0 |
| 3 | 5 | 2023-03-27 12:00:00 | 1 |
| 3 | 6 | NA | 0 |
| 4 | 7 | NA | 0 |
| 4 | 8 | 2023-03-27 13:00:00 | 1 |
| 5 | 9 | NA | NA |
| 5 | 10 | NA | NA |
内容的提问来源于stack exchange,提问作者JohnnyJohnson
相关产品推荐
相关产品推荐

