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

在R语言中基于条件用指定行值替换特定行值的tidyverse解法

用tidyverse处理RCT宽格式数据的替换与清理

先模拟一份和你场景匹配的宽格式数据,方便演示操作:

library(tidyverse)

set.seed(123)
df <- tibble(
  ID = c("ID1", "ID1", "ID1", "ID2", "ID3", "ID3", "ID4"),
  TIME = c("t1", "t1.5", "t2", "t1", "t1", "t1.5", "t2"),
  OUTCOME = c(45, 48, 52, 60, 40, 44, 55),
  OTHER_VAR = rnorm(7) # 保留其他协变量
)

# 你已有的需要替换的ID向量
pesky_IDs <- c("ID1", "ID3")

直接用tidyverse的链式操作一步到位:

cleaned_df <- df %>%
  # 按ID分组,只处理同一参与者的时间点
  group_by(ID) %>%
  # 提取t1.5的OUTCOME值,填充到同ID的所有行
  mutate(
    t1.5_val = if_else(TIME == "t1.5", OUTCOME, NA_real_),
    t1.5_val = fill(t1.5_val, .direction = "updown")
  ) %>%
  ungroup() %>%
  # 给目标ID的t1行替换OUTCOME值
  mutate(
    OUTCOME = case_when(
      ID %in% pesky_IDs & TIME == "t1" ~ t1.5_val,
      TRUE ~ OUTCOME
    )
  ) %>%
  # 清理临时列和t1.5行
  select(-t1.5_val) %>%
  filter(TIME != "t1.5")

代码逻辑说明

  • group_by(ID):把同一参与者的所有行归为一组,避免跨ID混淆数据
  • fill(t1.5_val, .direction = "updown"):把t1.5行的OUTCOME值复制到同ID的t1、t2行,这样t1行就能直接拿到要替换的值
  • case_when():精准控制替换范围——只给pesky_IDs里的ID的t1行替换值,其他行保持原样
  • 最后两步删掉临时辅助列和不需要的t1.5行,得到干净的数据集

多结局变量的扩展方案

如果你的数据有多个结局变量(比如OUTCOME1、OUTCOME2),可以用across()批量处理:

cleaned_df_multi <- df %>%
  group_by(ID) %>%
  # 批量提取所有结局变量的t1.5值
  mutate(
    across(starts_with("OUTCOME"), ~ if_else(TIME == "t1.5", ., NA_real_), .names = "{.col}_t1.5"),
    across(ends_with("_t1.5"), fill, .direction = "updown")
  ) %>%
  ungroup() %>%
  # 批量替换目标行的结局值
  mutate(
    across(starts_with("OUTCOME"), ~ case_when(
      ID %in% pesky_IDs & TIME == "t1" ~ get(str_c(cur_column(), "_t1.5")),
      TRUE ~ .
    ))
  ) %>%
  select(-ends_with("_t1.5")) %>%
  filter(TIME != "t1.5")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:15:57