R数据框基于另一列值对多列向量化重新编码的实现方法
R批量重计分题目作答数据的实现方案
核心思路:批量匹配q开头的题目列,提取每列对应的题目序号,再和每行的completed字段比较后重赋值,完全避免手动逐列编写逻辑。
方案1:tidyverse(dplyr)最简方案
符合常用的管道语法,代码简洁易维护:
library(tidyverse) want <- have %>% mutate(across( # 匹配所有q_开头的题目列 .cols = starts_with("q_"), # 逐列处理逻辑:列序号<=completed则保留原值,否则置0 .fns = ~ if_else(completed >= parse_number(cur_column()), .x, 0), # 自定义新列名,自动生成scored_1、scored_2格式 .names = "scored_{parse_number(.col)}" ))
方案2:无依赖的Base R方案
不需要加载任何第三方包,适合轻量运行场景:
# 提取所有q_开头的列名和对应题目序号 q_cols <- grep("^q_\\d+$", names(have), value = TRUE) q_nums <- as.integer(gsub("q_", "", q_cols)) # 批量生成scored列 for (i in seq_along(q_cols)) { have[[paste0("scored_", q_nums[i])]] <- ifelse( have$completed >= q_nums[i], have[[q_cols[i]]], 0 ) } want <- have
方案3:大体积数据集最优的data.table方案
针对十万行以上的大表,性能远高于前两种方案:
library(data.table) setDT(have) # 转换为data.table格式 q_cols <- grep("^q_\\d+$", names(have), value = TRUE) q_nums <- as.integer(gsub("q_", "", q_cols)) # 批量赋值新列 have[, paste0("scored_", q_nums) := Map( function(col, n) fifelse(completed >= n, col, 0), .SD, q_nums ), .SDcols = q_cols] want <- have[] # 输出结果
内容的提问来源于stack exchange,提问作者Kate N
相关产品推荐
相关产品推荐

