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

如何为每个受试者计算后在DataFrame中插入新行并循环执行?

问题描述

有一个包含9名受试者的DataFrame,每名受试者有8组治疗前后的结果数据,结构如下:

subIDtreatmentoutcome
14325affected_pre_10.45
14325affected_pre_20.25
14325unaffected_pre_11.05
14325unaffected_pre_21.23
14325affected_post_10.22
14325affected_post_20.45
14325unaffected_post_10.87
14325unaffected_post_20.34
18964affected_pre_10.90
18964affected_pre_21.13
18964unaffected_pre_10.55
18964unaffected_pre_20.23
18964affected_post_10.17
18964affected_post_21.22
18964unaffected_post_11.89
18964unaffected_post_20.76
39274affected_pre_10.88
39274affected_pre_20.12
39274unaffected_pre_10.05
39274unaffected_pre_20.34
39274affected_post_10.99
39274affected_post_20.32
39274unaffected_post_11.81
39274unaffected_post_21.34
.........

需要为每名受试者生成4个新行,计算规则:

  • row 1 = affected_pre_2 / affected_pre_1
  • row 2 = unaffected_pre_2 / unaffected_pre_1
  • row 3 = affected_post_2 / affected_post_1
  • row 4 = unaffected_post_2 / unaffected_post_1

尝试过以下代码,但收到summarise()已弃用的警告:

data %>%
bind_rows(data %>% summarise(subID = str_c(subID, lead(subID), sep = '_')) %>% na.omit() %>%
bind_cols(data %>% summarise(across(5:11, ~ . - lead(.))) %>% na.omit()))

注:across(5:11 ...)指实际拥有的多个结果变量(示例仅保留一个简化展示)。不确定是否需要用apply函数,也不清楚如何按受试者循环执行流程。

解决方案

用tidyverse工具链即可完成,核心思路是拆分treatment列信息后按组计算比值,具体步骤如下:

1. 加载依赖包

library(tidyverse)

2. 单结果变量的处理代码

# 生成比值数据
ratio_data <- data %>%
  # 拆分treatment列,提取状态、时间、序号信息
  separate(treatment, into = c("status", "time", "num"), sep = "_") %>%
  # 按受试者、状态、时间分组计算比值
  group_by(subID, status, time) %>%
  summarise(outcome = outcome[num == "2"] / outcome[num == "1"], .groups = "drop") %>%
  # 生成新的treatment列名称
  mutate(treatment = str_c(status, time, "ratio", sep = "_")) %>%
  # 调整列顺序与原数据一致
  select(subID, treatment, outcome)

# 若需将原数据与比值数据合并
combined_data <- bind_rows(data, ratio_data)

3. 多结果变量的适配处理

如果存在多个结果变量(对应原代码中的5:11列),只需修改summarise部分,用across批量处理:

ratio_data_multi <- data %>%
  separate(treatment, into = c("status", "time", "num"), sep = "_") %>%
  group_by(subID, status, time) %>%
  # 批量处理所有以outcome开头的列,也可改用5:11指定列位置
  summarise(across(starts_with("outcome"), ~ .[num == "2"] / .[num == "1"]), .groups = "drop") %>%
  mutate(treatment = str_c(status, time, "ratio", sep = "_")) %>%
  select(subID, treatment, everything())

代码说明

  • separate()将treatment拆分为状态(affected/unaffected)、时间(pre/post)、序号(1/2)三列,便于精准分组。
  • group_by(subID, status, time)确保每个受试者的每组状态-时间组合独立计算比值。
  • summarise()直接提取序号2的结果除以序号1的结果,避免循环或apply类函数的复杂操作。

内容的提问来源于stack exchange,提问作者A.R.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:07:48