如何基于var_x与对应is_deleted列提取首个符合条件的var_x值?
解决方案:新增首个符合条件的var_x值列
Tidyverse 实现
利用dplyr的数据操作能力和tidyr的重塑功能,先将宽表转为长表,匹配对应状态列后筛选出符合条件的记录,再取每行首个有效值合并回原数据:
library(tidyverse) # 提取所有var_x的编号(自动适配1-9的范围) var_nums <- str_extract(names(df), "(?<=var_)\\d+") %>% unique() %>% na.omit() %>% as.integer() df_result <- df %>% rownames_to_column("row_id") %>% # 展开var_x列 pivot_longer( cols = all_of(paste0("var_", var_nums)), names_to = "var_num", values_to = "var_value", names_prefix = "var_" ) %>% # 展开对应is_deleted列并匹配 left_join( df %>% rownames_to_column("row_id") %>% pivot_longer( cols = all_of(paste0("var_", var_nums, "_is_deleted")), names_to = "del_num", values_to = "is_deleted", names_pattern = "(\\d+)_is_deleted" ) %>% select(row_id, del_num, is_deleted), by = c("row_id", "var_num" = "del_num") ) %>% # 筛选状态为No的记录,取每行第一个 filter(is_deleted == "No") %>% group_by(row_id) %>% slice_head(n = 1) %>% ungroup() %>% select(row_id, var = var_value) %>% # 合并回原数据 right_join(df %>% rownames_to_column("row_id"), by = "row_id") %>% select(-row_id, everything(), var) print(df_result)
Base R 实现
通过遍历每行数据,依次检查每个var_x对应的状态列,找到首个标记为"No"的var_x值:
# 提取所有var_x的编号 var_nums <- unique(na.omit(as.integer(sub("var_(\\d+).*", "\\1", names(df))))) # 定义单行处理函数 get_first_valid <- function(row) { for(num in var_nums) { del_col <- paste0("var_", num, "_is_deleted") var_col <- paste0("var_", num) # 跳过NA状态,找到第一个"No"对应的var值 if(!is.na(row[del_col]) && row[del_col] == "No") { return(row[var_col]) } } return(NA) # 无符合条件时返回NA } # 应用到每行生成新列 df$var <- apply(df, 1, get_first_valid) print(df)
两种方法都能自动适配1-9个var_x列的场景,处理后即可得到预期的var列。
内容的提问来源于stack exchange,提问作者pure_func
相关产品推荐
相关产品推荐

