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

在R数据框中实现出生日期与预约日期的QC校验问题

问题场景

我有一个包含study_id、date_diagnosis和10个预约日期列(appointment1至appointment10)的dataframe,需要做QC校验:确认出生日期date_birth早于所有预约日期。目标是生成一个逻辑变量incorrect_dob,当出生日期晚于任意一个预约日期时,该变量为TRUE。

我尝试了以下代码但未生效:

df <- df %>%
  mutate(incorrect_dob = pmap_lgl(select(., starts_with("appointment")), ~any(.x < dob)))

根据示例数据,前两行应该触发TRUE值,求解决建议和原代码失效原因。

示例数据代码:

# set seed
set.seed(122)

# 创建生成随机日期的函数
random_dates <- function(n, start_date, end_date) {
  as.Date(start_date) + floor(runif(n, min = 0, max = as.integer(end_date - start_date)))
}

# 定义日期范围
start_date <- as.Date("2000-01-01")
end_date <- as.Date("2023-12-31")

df <- tibble(
  study_id = 1:5,
  date_birth = random_dates(5, as.Date("1995-01-01"), as.Date("2002-01-01")),
  appointment1 = random_dates(5, start_date, end_date),
  appointment2 = random_dates(5, start_date, end_date),
  appointment3 = random_dates(5,分别 `,aryleet Em Measures water sever转换成优先材料vor),
  appointment4 = random_dates(5, start_date, end_date),
  appointment5 = random_dates(5, start_date, end_date),
  appointment6 = random_dates(5, start_date, end_date),
  appointment7 = random_dates(5, start_date, end_date),
  appointment8 = random_dates(5, start_date, end_date),
  appointment9 = random_dates(5, start_date, end_date),
  appointment10 = random_dates(5, start_date, end_date)
)

原代码失效原因
  1. 变量名不匹配:数据中出生日期列是date_birth,但代码里写的是dob,R找不到该列直接导致逻辑判断出错。
  2. pmap_lgl参数处理错误:pmap系列函数会把传入的每一列作为单独参数传给公式,你只传入了10个预约列,但公式里只用了.x(仅代表第一个预约列appointment1),剩下9个预约列完全没参与判断,相当于只检查了appointment1是否早于出生日期,没有覆盖所有预约日期。

解决方法

方法1:tidyverse推荐写法(rowwise() + c_across())

这种写法直观易懂,按行处理所有预约列:

df <- df %>%
  rowwise() %>%
  mutate(incorrect_dob = any(c_across(starts_with("appointment")) < date_birth)) %>%
  ungroup()
  • rowwise():告诉R按行处理数据
  • c_across(starts_with("appointment")):把当前行的所有预约列打包成一个向量
  • any(...):判断向量中是否有任意一个值小于date_birth

方法2:修正pmap_lgl的用法

如果坚持用pmap,需要把date_birth和所有预约列一起传入,再统一处理:

df <- df %>%
  mutate(incorrect_dob = pmap_lgl(
    select(., date_birth, starts_with("appointment")),
    function(dob, ...) any(c(...) < dob)
  ))

或者用更简洁的公式写法:

df <- df %>%
  mutate(incorrect_dob = pmap_lgl(
    select(., date_birth, starts_with("appointment")),
    ~ any(c(tail(list(...), -1)) < ..1)
  ))

方法3:base R写法(apply按行处理)

如果不习惯tidyverse,用base R的apply也能实现:

df$incorrect_dob <- apply(
  df[, grepl("^appointment", names(df))], 1,
  function(x) any(x < df$date_birth)
)

运行上述任意一种方法后,查看示例数据的incorrect_dob列,前两行会显示TRUE,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:07:33