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

如何基于列名字符串标识在R中批量应用条件逻辑

基于列名共同标识批量替换NA的R语言解决方案

针对需求——当对应物质的_yn列取值为no时,将该物质的freqDays_和quant_列中的NA替换为0,以下是几种无需宽长表转换的高效解决方案:

方法一:tidyverse手动指定列(适合少量物质)

如果研究的物质数量较少(如示例中的酒精、大麻),可以直接用dplyr::across针对性处理每组列:

library(tidyverse)

set.seed(1)
df <- data.frame(alc_yn = factor(x = rep(x = c("no", "yes"), 
                                         each = 5),
                                 levels = c("no", "yes")),
                 freqDays_alc = c(rep(NA,5), sample(1:10,5,replace=F)),
                 quant_alc =  c(rep(NA,5), sample(1:50,5,replace=F)),
                 cann_yn = factor(x = rep(x = c("yes", "no"), 
                                         each = 5),
                                 levels = c("no", "yes")),
                 freqDays_cann = c(sample(1:10,5,replace=F),rep(NA,5)),
                 quant_cann = c(sample(1:50,5,replace=F),rep(NA,5)))

# 批量替换NA为0
df_processed <- df %>%
  # 处理酒精相关列:当alc_yn为no时,替换freqDays_alc和quant_alc的NA为0
  mutate(across(c(freqDays_alc, quant_alc), 
                ~ifelse(alc_yn == "no" & is.na(.), 0, .))) %>%
  # 处理大麻相关列:当cann_yn为no时,替换freqDays_cann和quant_cann的NA为0
  mutate(across(c(freqDays_cann, quant_cann), 
                ~ifelse(cann_yn == "no" & is.na(.), 0, .)))

# 验证结果与预期一致
set.seed(1)
df_sol <- data.frame(alc_yn = factor(x = rep(x = c("no", "yes"), 
                                         each = 5),
                                 levels = c("no", "yes")),
                     freqDays_alc = c(rep(0,5), sample(1:10,5,replace=F)),
                     quant_alc =  c(rep(0,5), sample(1:50,5,replace=F)),
                     cann_yn = factor(x = rep(x = c("yes", "no"), 
                                              each = 5),
                                      levels = c("no", "yes")),
                     freqDays_cann = c(sample(1:10,5,replace=F),rep(0,5)),
                     quant_cann = c(sample(1:50,5,replace=F),rep(0,5)))

all.equal(df_processed, df_sol)
# [1] TRUE

方法二:tidyverse通用循环(适合多物质)

如果需要处理的物质数量较多,可通过提取物质标识循环处理,避免重复代码:

library(tidyverse)

# 定义所有需要处理的物质标识
substances <- c("alc", "cann")

df_processed <- df
for (sub in substances) {
  # 拼接对应物质的_yn列名
  yn_col <- paste0(sub, "_yn")
  # 匹配该物质对应的freqDays_和quant_列
  value_cols <- matches(paste0("_", sub, "$"))
  
  df_processed <- df_processed %>%
    mutate(across(all_of(value_cols), 
                  ~ifelse(.data[[yn_col]] == "no" & is.na(.), 0, .)))
}

方法三:Base R解决方案(无需加载包)

如果不想依赖tidyverse包,可直接用Base R实现相同逻辑:

substances <- c("alc", "cann")

df_processed <- df
for (sub in substances) {
  # 获取_yn列和对应数值列的索引
  yn_idx <- which(colnames(df_processed) == paste0(sub, "_yn"))
  value_idx <- grep(paste0("_", sub, "$"), colnames(df_processed))
  
  # 替换符合条件的NA为0
  df_processed[df_processed[, yn_idx] == "no", value_idx] <- lapply(
    df_processed[df_processed[, yn_idx] == "no", value_idx],
    function(x) ifelse(is.na(x), 0, x)
  )
}

以上三种方法均无需进行宽长表转换,可根据实际需求选择合适的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 18:42:41