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

如何基于双条件补全R数据框的字符与数值列?

问题

我有一个包含200余列、数百行的数据框,以下是示例数据:

df_tocomplate <- data.frame(
  id = c("id1", "id2", "id3"),
  vara.test = c("", "yes", ""), 
  vara.bb = c("yes", "", ""), 
  vara.some = c("", "yes", ""),
  vara = c("bb", "test | some", ""),
  varb.other = c("yes", "", "yes"),
  varb.blop = c("", "yes", "yes"), 
  varb.some = c("yes", "", ""), 
  varb.test = c("", "", "yes"),
  varb = c("other | some", "blop", "other | blop | test"),
  varc.num1 = c(100, 25, 50),
  varc.num2 = c(NA, 75, 25),
  varc.num3 = c(NA, NA, 25),
  varc = c("num1: 100", "num1: 25 | num2: 75", "num1: 50 | num2: 25 | num3: 25"),
  vard.glo1 = c(NA, 15, NA),
  vard.glo2 = c(NA, 85, NA),
  vard.glo3 = c(NA, NA, 100),
  vard = c("", "glo1: 15 | glo2: 85", "glo3: 100")
)

示例中,vara.(...)这类子列由vara主列生成,varb.(...)、varc.(...)、vard.(...)同理。我需要构建一个函数补全这些子列,规则如下:

  • 字符型主列(如vara、varb):若主列非空且对应子列为空,则子列填充"no";
  • 数值型主列(如varc、vard):若主列非空且对应子列为空,则子列填充0。

已将主列分为两类:

var_names_char = c("vara", "varb")
var_names_num <- c("varc", "vard")

期望得到的结果如下:

df_result <- data.frame(
  id = c("id1", "id2", "id3"),
  vara.test = c("no", "yes", ""), 
  vara.bb = c("yes", "no", ""), 
  vara.some = c("no", "yes", ""),
  vara = c("bb", "test | some", ""),
  varb.other = c("yes", "no", "yes"),
  varb.blop = c("no", "yes", "yes"), 
  varb.some = c("yes", "no", "no"), 
  varb.test = c("no", "no", "yes"),
  varb = c("other | some", "blop", "other | blop | test"),
  varc.num1 = c(100, 25, 50),
  varc.num2 = c(0, 75, 25),
  varc.num3 = c(0, 0, 25),
  varc = c("num1: 100", "num1: 25 | num2: 75", "num1: 50 | num2: 25 | num3: 25"),
  vard.glo1 = c(NA, 15, 0),
  vard.glo2 = c(NA, 85, 0),
  vard.glo3 = c(NA, 0, 100),
  vard = c("", "glo1: 15 | glo2: 85", "glo3: 100")
)
解决方案

可以编写一个通用函数,遍历两类主列,分别处理对应的子列:

fill_subcolumns <- function(df, char_vars, num_vars) {
  # 处理字符型主列对应的子列
  for (var in char_vars) {
    # 获取当前主列的所有子列(列名以var.开头)
    sub_cols <- grep(paste0("^", var, "\\."), colnames(df), value = TRUE)
    # 主列非空的行索引
    main_non_empty <- df[[var]] != ""
    
    for (col in sub_cols) {
      # 子列为空且主列非空的位置,填充"no"
      fill_pos <- main_non_empty & (df[[col]] == "")
      df[[col]][fill_pos] <- "no"
    }
  }
  
  # 处理数值型主列对应的子列
  for (var in num_vars) {
    # 获取当前主列的所有子列(列名以var.开头)
    sub_cols <- grep(paste0("^", var, "\\."), colnames(df), value = TRUE)
    # 主列非空的行索引
    main_non_empty <- df[[var]] != ""
    
    for (col in sub_cols) {
      # 子列为NA且主列非空的位置,填充0
      fill_pos <- main_non_empty & is.na(df[[col]])
      df[[col]][fill_pos] <- 0
    }
  }
  
  return(df)
}

函数说明

  • 遍历字符型主列:通过正则匹配找到所有以主列名.开头的子列,筛选出主列非空且子列为空的行,填充"no";
  • 遍历数值型主列:同理匹配子列,筛选主列非空且子列为NA的行,填充0;
  • 函数直接修改输入数据框并返回,适合处理大数据量。

使用方式

调用函数传入数据框和两类主列列表即可:

df_result <- fill_subcolumns(df_tocomplate, var_names_char, var_names_num)

验证结果是否符合预期:

all.equal(df_result, df_result) # 返回TRUE说明结果匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 10:42:53