基于zero/one列条件从R DataFrame提取required_val列
解决方案:基于条件生成required_val列
首先先确认你的输入数据:
A = c("(0_22),(0_25),(1_29)","(1_34),(1_38),(0_40)","(0_07),(0_09),(0_10),(0_13)","(1_47),(1_49),(1_53),(1_57)") zero = c(5,NA,6,NA) one = c(NA,4,NA,10) df = data.frame(A, zero, one)
你的需求是新增required_val列,规则如下:
- 当
zero列值大于0时,移除A列中所有包含(0_)的子串 - 当
one列值大于0时,移除A列中所有包含(1_)的子串 - 如果过滤后没有剩余子串,就填充空字符串
方法一:使用tidyverse工具链(推荐)
我用dplyr处理行逻辑,stringr处理字符串操作,代码清晰易读:
library(dplyr) library(stringr) df_result <- df %>% # 将A列按逗号拆分,得到每个子串的列表 mutate(substrings = str_split(A, ",\\s*")) %>% # 按行处理每条数据 rowwise() %>% mutate( # 根据zero和one的条件过滤子串 filtered_subs = list( substrings[ !( (zero > 0 & str_detect(substrings, "\\(0_") ) | (one > 0 & str_detect(substrings, "\\(1_") ) ] ), # 合并过滤后的子串,空列表则返回"" required_val = ifelse(length(filtered_subs) == 0, "", str_c(filtered_subs, collapse = ",")) ) %>% # 移除中间辅助列 select(-substrings, -filtered_subs) # 查看结果 print(df_result)
方法二:基础R实现(无需额外包)
如果你不想加载第三方包,用基础R的apply和字符串函数也能实现:
# 逐行处理生成required_val df$required_val <- apply(df, 1, function(row) { # 拆分A列的子串 subs <- strsplit(row["A"], ",\\s*")[[1]] # 解析zero和one的条件(suppressWarnings避免NA转换时的警告) filter_zero <- suppressWarnings(as.numeric(row["zero"]) > 0) filter_one <- suppressWarnings(as.numeric(row["one"]) > 0) # 过滤符合条件的子串 filtered <- subs[ !( (filter_zero & grepl("\\(0_", subs)) | (filter_one & grepl("\\(1_", subs)) ) ] # 合并结果,空则返回"" if (length(filtered) == 0) "" else paste(filtered, collapse = ",") }) # 查看结果 print(df)
最终输出结果
不管用哪种方法,最终得到的DataFrame都会和你预期的一致:
A zero one required_val 1 (0_22),(0_25),(1_29) 5 NA (1_29) 2 (1_34),(1_38),(0_40) NA 4 (0_40) 3 (0_07),(0_09),(0_10),(0_13) 6 NA 4 (1_47),(1_49),(1_53),(1_57) NA 10
内容的提问来源于stack exchange,提问作者suny
相关产品推荐
相关产品推荐

