基于两张表生成文本文件的R语言问题:多位数阶段适配
解决R代码适配多位数阶段(如phase12)的问题
问题背景
需求是基于两张数据表生成特定格式的文本文件,每个Interstage需包含指定字段,信号组(SG)的状态转换需遵循以下规则:
- 从活跃阶段转为非活跃阶段时,输出格式为
SGx -127 "insert value later manually" - 从非活跃转为活跃阶段时,输出格式为
SGx "insert value later manually" 127
原代码在处理phase12这类多位数阶段时无法正常工作,因为阶段判断逻辑错误匹配了多位数阶段的前缀。
原代码问题分析
原代码中使用grepl("phase1|phase2", active_phases)判断信号组的活跃阶段,这种方式会把phase12错误识别为phase1,导致状态转换的判断完全错误。正确的逻辑应该是提取每个phase列的数字部分,对比Interstage的from_stage和to_stage,判断信号组在这两个阶段的活跃状态,进而确定输出格式。
修正后的完整代码
tabel_signal_groups <- data.frame( Signal_Group = c("SG1", "SG2", "SG3", "SG4"), phase1 = c("x", "", "x","x"), phase2 = c("", "x", "","x"), phase12 = c("", "", "","x"), stringsAsFactors = FALSE # 避免因子类型导致的列名处理问题 ) tabel <- data.frame( Interstage = c("ISt112", "ISt23", "ISt31"), from_stage = c(1, 2, 3), to_stage = c(12, 3, 1), length = c(0, 5, 7), stringsAsFactors = FALSE ) # 生成每个Interstage的文本字符串函数 genereer_text_string <- function(row, signal_groups_df) { # 提取当前Interstage的起始和目标阶段数字 from_stage <- as.integer(row["from_stage"]) to_stage <- as.integer(row["to_stage"]) text_string <- paste0( "$", row["Interstage"], "\n", "ISt name : St", from_stage, "->St", to_stage, "\n", "ISt description : Source: Stage sequence plan\n", "ISt Description: \n", "INTERSTAGE_number : ", row["Interstage"], "\n", "Length [s] : ", row["length"], "\n", "From stage : ", from_stage, "\n", "To stage : ", to_stage, "\n" ) # 遍历每个信号组,判断状态转换 for (i in seq_along(signal_groups_df$Signal_Group)) { signal_group <- signal_groups_df$Signal_Group[i] # 构建起始和目标阶段对应的列名(如phase1、phase12) from_phase_col <- paste0("phase", from_stage) to_phase_col <- paste0("phase", to_stage) # 检查信号组在起始和目标阶段是否活跃("x"表示活跃) active_in_from <- signal_groups_df[i, from_phase_col] == "x" active_in_to <- signal_groups_df[i, to_phase_col] == "x" # 根据状态转换生成对应行 if (active_in_from && !active_in_to) { # 活跃转非活跃 text_string <- paste0(text_string, signal_group, " -127 \"insert value later manually\"\n") } else if (!active_in_from && active_in_to) { # 非活跃转活跃 text_string <- paste0(text_string, signal_group, " \"insert value later manually\" 127\n") } # 状态不变的情况(都活跃或都不活跃)不输出对应行 } text_string <- paste0(text_string, "$\n") return(text_string) } # 生成所有Interstage的文本 alle_text_strings <- apply(tabel, 1, genereer_text_string, signal_groups_df = tabel_signal_groups) # 输出结果 cat(alle_text_strings)
关键修改说明
- 阶段列名匹配逻辑:不再用字符串模糊匹配,而是直接用
paste0("phase", 阶段数字)构建准确的列名,确保phase12这类多位数阶段能被正确定位。 - 状态转换判断:明确检查信号组在
from_stage和to_stage的活跃状态,仅当状态发生变化时才输出对应行:- 起始阶段活跃、目标阶段不活跃:输出
-127格式(活跃转非活跃) - 起始阶段不活跃、目标阶段活跃:输出
127格式(非活跃转活跃)
- 起始阶段活跃、目标阶段不活跃:输出
- 数据类型处理:添加
stringsAsFactors = FALSE避免因子类型导致的列名读取错误。
示例输出
$ISt112 ISt name : St1->St12 ISt description : Source: Stage sequence plan ISt Description: INTERSTAGE_number : ISt112 Length [s] : 0 From stage : 1 To stage : 12 SG1 -127 "insert value later manually" SG3 -127 "insert value later manually" SG4 "insert value later manually" 127 $ $ISt23 ISt name : St2->St3 ISt description : Source: Stage sequence plan ISt Description: INTERSTAGE_number : ISt23 Length [s] : 5 From stage : 2 To stage : 3 SG2 -127 "insert value later manually" $ $ISt31 ISt name : St3->St1 ISt description : Source: Stage sequence plan ISt Description: INTERSTAGE_number : ISt31 Length [s] : 7 From stage : 3 To stage : 1 SG1 "insert value later manually" 127 SG3 "insert value later manually" 127 $
内容的提问来源于stack exchange,提问作者Philippe Goethals
相关产品推荐
相关产品推荐

