在R中实现括号后连续/固定字符的筛选处理咨询
在R中实现连续0/1组的取值规则
首先,咱们先明确需求规则:
- 从每个括号项中提取前缀(0或1)和后缀数值
- 对连续相同前缀的组:
- 前缀为0时,保留后缀数值最小的项
- 前缀为1时,保留后缀数值最大的项
- 非连续的不同前缀项保持原顺序,只处理连续组
步骤1:准备数据
先把你提供的原始数据转换成R的数据框:
df <- data.frame( date = c("1/12/2017 0:15", "1/12/2017 0:30", "1/12/2017 0:45", "1/12/2017 1:00", "1/12/2017 1:15"), val = c("(0_04),(1_08),(0_12),(1_14)", "(0_22),(0_25),(1_29)", "(1_34),(1_38),(0_40),(1_44)", "(1_47),(1_49),(1_53),(1_57),(0_59)", "(0_07),(0_09),(0_10),(0_13),(1_14)"), cal_val = c("(0_04),(1_08),(0_12),(1_14)", "(0_22),(1_29)", "(1_38),(0_40),(1_44)", "(1_57),(0_59)", "(0_7),(1_14)"), stringsAsFactors = FALSE )
步骤2:编写处理函数
我写了一个process_str函数来处理每个字符串,核心是分组处理连续的0/1项:
library(stringr) process_str <- function(s) { # 提取所有括号内的内容(比如从"(0_22),(0_25)"中拿到c("0_22", "0_25")) items <- str_extract_all(s, "(?<=\\()\\d+_\\d+(?=\\))")[[1]] # 拆分每个项的前缀(0/1)和后缀数值 prefix <- str_extract(items, "^\\d") num <- as.integer(str_extract(items, "(?<=_)\\d+")) # 生成分组标识:连续相同前缀的项归为一组 groups <- cumsum(c(TRUE, prefix[-1] != prefix[-length(prefix)])) # 按组处理:0组取最小数值项,1组取最大数值项,同时统一数值格式(去掉前导0) processed_items <- lapply(split(data.frame(prefix=prefix, num=num), groups), function(group) { current_prefix <- unique(group$prefix) selected_num <- if (current_prefix == "0") min(group$num) else max(group$num) paste0(current_prefix, "_", selected_num) }) # 把处理后的项拼接回原始的括号分隔格式 paste0("(", paste(unlist(processed_items), collapse="),("), ")") }
步骤3:应用函数并验证结果
把函数应用到val列,然后和预期的cal_val对比:
df$processed_val <- sapply(df$val, process_str) # 查看结果 print(df[, c("date", "val", "processed_val", "cal_val")])
运行后输出的结果:
date val processed_val cal_val 1 1/12/2017 0:15 (0_04),(1_08),(0_12),(1_14) (0_4),(1_8),(0_12),(1_14) (0_04),(1_08),(0_12),(1_14) 2 1/12/2017 0:30 (0_22),(0_25),(1_29) (0_22),(1_29) (0_22),(1_29) 3 1/12/2017 0:45 (1_34),(1_38),(0_40),(1_44) (1_38),(0_40),(1_44) (1_38),(0_40),(1_44) 4 1/12/2017 1:00 (1_47),(1_49),(1_53),(1_57),(0_59) (1_57),(0_59) (1_57),(0_59) 5 1/12/2017 1:15 (0_07),(0_09),(0_10),(0_13),(1_14) (0_7),(1_14) (0_7),(1_14)
补充说明
- 这个函数依赖
stringr包,如果你没安装的话,先运行install.packages("stringr")安装 - 函数会自动处理任意长度的连续组,不管是2个还是多个连续的0/1项
- 如果不需要统一数值格式(保留前导0),可以把生成项的代码改回直接取原item的逻辑:
group$item[which.min(group$num)]或group$item[which.max(group$num)]
内容的提问来源于stack exchange,提问作者suny
相关产品推荐
相关产品推荐

