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

R语言计算vasopressor_duration时新列全NA问题求助(附可复现代码)

问题:计算升压药时长时新列全为NA的解决方法

问题背景

需要生成vasopressor_on(指定列的最小值)、vasopressor_off(指定列的最大值),并计算两者的时长vasopressor_duration,要求NA行保留NA或转为0。简化数据集测试正常,但在真实数据集(test_df)中,添加时长计算代码后,所有新生成列都变成NA;移除时长计算代码后,vasopressor_on和vasopressor_off能正常生成值。

可复现代码如下:

study_ID <- c(5,6,7)
randomisation <- (c("2021-01-01 11:00", NA, "2021-01-03 10:00"))
water_on <- (c("2021-01-01 13:00", NA,"2021-01-04 09:45"))
water_off <- (c("2021-01-01 18:00", NA,"2021-01-04 11:00"))
trial_A <- data.frame(study_ID, randomisation, water_on, water_off)

trial_A_1 <- trial_A  %>% dplyr::mutate(across(c(randomisation, water_on, water_off), ymd_hm))

robustmax <- function(x) {if (length(x)>0) max(x) else -Inf} 
robustmin <- function(x) {if (length(x)>0) min(x) else Inf}

Primary <- trial_A_1 %>% rowwise() %>% 
  dplyr::mutate(vasopressor_on = robustmin(c_across(c(randomisation, water_on, water_off)))) %>% 
  dplyr::mutate(vasopressor_off = robustmax(c_across(c(randomisation, water_on, water_off)))) %>% 
  dplyr::mutate(vasopressor_duration = (vasopressor_on %--% vasopressor_off) %>% as.duration() / dhours()) %>% ungroup()

# 真实数据集代码(修正原拼写错误:test_ df → test_df)
test_df <- data.frame(
  true_adrenaline_on = as.POSIXct(
    rep(c("2020-08-31 13:05:00", NA, "2020-09-17 20:58:00", NA), c(1L, 3L, 1L, 5L)),
    tz = "UTC"
  ),
  true_noradrenaline_on = as.POSIXct(
    c(
      "2020-08-31 13:05:00", "2020-09-03 14:00:00", NA, "2020-09-17 16:00:00",
      "2020-09-17 23:00:00", NA, "2020-09-21 14:10:00", "2020-09-24 14:17:00",
      NA, "2020-09-28 14:20:00"
    ),
    tz = "UTC"
  ),
  true_vasopressin_on = as.POSIXct(
    rep(c(NA, "2020-09-18 09:00:00", NA, "2020-09-28 19:00:00"), rep(c(4L, 1L), 2)),
    tz = "UTC"
  ),
  true_phenylephrine_on = as.POSIXct(rep(NA_character_, 10L), tz = "UTC"),
  true_metaraminol_on = as.POSIXct(rep(NA_character_, 10L), tz = "UTC"),
  true_adrenaline_off = as.POSIXct(
    rep(c("2020-09-01 08:00:00", NA, "2020-09-18 09:00:00", NA), c(1L, 3L, 1L, 5L)),
    tz = "UTC"
  ),
  true_noradrenaline_off = as.POSIXct(
    c(
      "2020-09-01 06:00:00", "2020-09-04 22:00:00", NA, "2020-09-17 18:00:00",
      "2020-09-21 07:00:00", NA, "2020-09-21 22:00:00", "2020-09-25 00:00:00",
      NA, "2020-09-29 16:00:00"
    ),
    tz = "UTC"
  ),
  true_vasopressin_off = as.POSIXct(
    rep(c(NA, "2020-09-21 07:00:00", NA, "2020-09-29 04:00:00"), rep(c(4L, 1L), 2)),
    tz = "UTC"
  ),
  true_phenylephrine_off = as.POSIXct(rep(NA_character_, 10L), tz = "UTC"),
  true_metaraminol_off = as.POSIXct(rep(NA_character_, 10L), tz = "UTC")
)

# 原真实数据集处理代码
Primary <- test_df %>% rowwise() %>% 
  dplyr::mutate(vasopressor_on = robustmin(c_across(c(true_adrenaline_on, true_noradrenaline_on, true_vasopressin_on,true_phenylephrine_on,true_metaraminol_on)))) %>% 
  dplyr::mutate(vasopressor_off = robustmax(c_across(c(true_adrenaline_off, true_noradrenaline_off, true_vasopressin_off,true_phenylephrine_off,true_metaraminol_off)))) %>% 
  dplyr::mutate(vasopressor_duration = (vasopressor_on %--% vasopressor_off) %>% as.duration() / dhours()) %>% ungroup()

问题原因

  1. robustmin/robustmax函数逻辑错误:当某一行所有值都是NA时,c_across返回的向量长度仍大于0,函数会执行min(x)/max(x),结果为NA;全NA行生成的NA值会导致后续时长计算出错,进而引发所有新列异常。
  2. 时长计算未处理异常情况:当vasopressor_on晚于vasopressor_off时,计算出的时长为负数,且未处理NA值的情况,导致结果不符合预期。

解决方案

1. 修正鲁棒性函数

过滤NA值后再判断是否有有效值,不存在有效值时返回NA,避免后续时间区间计算出错:

robustmax <- function(x) {
  x_non_na <- na.omit(x)
  if (length(x_non_na) > 0) max(x_non_na) else NA
} 

robustmin <- function(x) {
  x_non_na <- na.omit(x)
  if (length(x_non_na) > 0) min(x_non_na) else NA
}

2. 修正时长计算逻辑

判断vasopressor_on和vasopressor_off的有效性与时间顺序,符合要求则计算时长,否则返回NA或0:

library(dplyr)
library(lubridate)

# 处理真实数据集
Primary <- test_df %>% rowwise() %>% 
  mutate(vasopressor_on = robustmin(c_across(c(true_adrenaline_on, true_noradrenaline_on, true_vasopressin_on, true_phenylephrine_on, true_metaraminol_on)))) %>% 
  mutate(vasopressor_off = robustmax(c_across(c(true_adrenaline_off, true_noradrenaline_off, true_vasopressin_off, true_phenylephrine_off, true_metaraminol_off)))) %>% 
  mutate(vasopressor_duration = case_when(
    is.na(vasopressor_on) | is.na(vasopressor_off) ~ NA_real_,
    vasopressor_on > vasopressor_off ~ 0,  # 若开始晚于结束,返回0,可按需调整
    TRUE ~ as.duration(vasopressor_on %--% vasopressor_off) / dhours()
  )) %>% 
  ungroup()

验证结果

运行修正后的代码后:

  • 非NA行能正常生成vasopressor_on、vasopressor_off和对应的时长
  • 全NA行的vasopressor_on、vasopressor_off和vasopressor_duration均为NA,符合需求
  • 若出现vasopressor_on晚于vasopressor_off的情况,时长返回0(可根据实际需求调整该逻辑)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:14:58