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

使用case_when处理日期时遇向量长度不匹配警告的解决问询

解决日期分组时的向量长度不匹配警告问题

问题场景

你有如下数据集和日期向量:

my_data <- data.frame(date = as.Date(c("2022-03-08","2023-03-07","2022-11-29","2024-02-22")),
                      value = 1:4)

tox_date_1q <- as.Date(c("2022-03-08","2023-03-07","2024-02-21"))
tox_date_3q <- as.Date(c("2022-06-21","2022-09-14","2022-11-29","2023-06-05","2023-09-13","2023-11-14"))

想要给my_data添加group列,将每行分为指定类别,但运行以下代码时出现向量长度不匹配的警告:

my_data <- my_data |>
  mutate(group = case_when(
    date %in% tox_date_1q ~ "tox_date_1q",
    date %in% tox_date_3q ~ "tox_date_3q",
    date > as.Date(tox_date_1q-30) & date < as.Date(tox_date_1q+30) ~ "tox_period_1q",
    date > as.Date(tox_date_3q-30) & date < as.Date(tox_date_3q+30) ~ "tox_period_3q",
    .default = "other"
  ))

警告信息:

Warning message:
There were 4 warnings in `mutate()`.
The first warning was:
ℹ In argument: `group = case_when(...)`.
Caused by warning in `>.default`:
! longer object length is not a multiple of shorter object length

问题原因

问题出在判断日期是否在前后30天区间的代码段:

date > as.Date(tox_date_1q-30) & date < as.Date(tox_date_1q+30) ~ "tox_period_1q",
date > as.Date(tox_date_3q-30) & date < as.Date(tox_date_3q+30) ~ "tox_period_3q",

这里date是长度为4的向量(对应my_data的4行),而tox_date_1q是长度为3的向量,tox_date_3q是长度为6的向量。R会尝试循环较短的向量来匹配较长的向量长度,这不仅触发警告,还会导致逻辑错误——你需要判断的是单个日期是否落在任意一个tox_date的前后30天范围内,而非循环比较向量元素。

解决方案

方法1:使用rowwise()逐行处理

通过rowwise()让每行单独计算,结合any()判断当前日期是否满足任意一个区间条件:

library(dplyr)

my_data <- my_data |>
  rowwise() |>
  mutate(
    group = case_when(
      date %in% tox_date_1q ~ "tox_date_1q",
      date %in% tox_date_3q ~ "tox_date_3q",
      any(date > tox_date_1q - 30 & date < tox_date_1q + 30) ~ "tox_period_1q",
      any(date > tox_date_3q - 30 & date < tox_date_3q + 30) ~ "tox_period_3q",
      .default = "others"
    )
  ) |>
  ungroup()

方法2:使用purrr::map_lgl()批量判断

借助purrr包的map_lgl()遍历每个日期,生成逻辑向量后再分组:

library(dplyr)
library(purrr)

my_data <- my_data |>
  mutate(
    # 先判断每个日期是否在1q的任意区间内
    in_1q_period = map_lgl(date, ~any(.x > tox_date_1q - 30 & .x < tox_date_1q + 30)),
    # 判断每个日期是否在3q的任意区间内
    in_3q_period = map_lgl(date, ~any(.x > tox_date_3q - 30 & .x < tox_date_3q + 30)),
    # 生成group列
    group = case_when(
      date %in% tox_date_1q ~ "tox_date_1q",
      date %in% tox_date_3q ~ "tox_date_3q",
      in_1q_period ~ "tox_period_1q",
      in_3q_period ~ "tox_period_3q",
      .default = "others"
    )
  ) |>
  # 移除临时逻辑列
  select(-in_1q_period, -in_3q_period)

两种方法都能解决向量长度不匹配的问题,且逻辑符合需求:优先匹配精确日期,再判断是否在任意目标日期的前后30天区间,最后归为其他类别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 07:45:14