feat(dc): Add multi-metric transformation feature (direction 1+2)
Summary: - Implement intelligent multi-metric grouping detection algorithm - Add direction 1: timepoint-as-row, metric-as-column (analysis format) - Add direction 2: timepoint-as-column, metric-as-row (display format) - Fix column name pattern detection (FMA___ issue) - Maintain original Record ID order in output - Add full-select/clear buttons in UI - Integrate into TransformDialog with Radio selection - Update 3 documentation files Technical Details: - Python: detect_metric_groups(), apply_multi_metric_to_long(), apply_multi_metric_to_matrix() - Backend: 3 new methods in QuickActionService - Frontend: MultiMetricPanel.tsx (531 lines) - Total: ~1460 lines of new code Status: Fully tested and verified, ready for production
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# 工具C(Tool C)- 科研数据编辑器 - 当前状态与开发指南
|
||||
|
||||
> **最后更新**: 2025-12-10
|
||||
> **当前版本**: Day 5-8 MVP + 功能按钮 + NA处理 + Pivot优化 + UX重大改进
|
||||
> **开发进度**: Python微服务 ✅ | Session管理 ✅ | AI代码生成 ✅ | 前端完整 ✅ | 通用组件 ✅ | 功能按钮✅(7个)| NA处理✅ | Pivot优化✅ | **UX优化✅(筛选/行号/滚动条/全量数据)**
|
||||
> **最后更新**: 2025-12-21
|
||||
> **当前版本**: Day 5-8 MVP + 功能按钮 + NA处理 + Pivot优化 + UX重大改进 + **多指标转换✅**
|
||||
> **开发进度**: Python微服务 ✅ | Session管理 ✅ | AI代码生成 ✅ | 前端完整 ✅ | 通用组件 ✅ | 功能按钮✅(7个)| NA处理✅ | Pivot优化✅ | UX优化✅ | **多指标转换✅(方向1+2)**
|
||||
|
||||
---
|
||||
|
||||
@@ -21,7 +21,144 @@
|
||||
|
||||
---
|
||||
|
||||
## ✅ 已完成功能(Day 1-8)
|
||||
## ✅ 已完成功能(Day 1-9)
|
||||
|
||||
### 🎉 Day 9 多指标转换功能(2025-12-21)✅
|
||||
|
||||
#### 1. 功能概述
|
||||
**医学研究专用的多指标重复测量数据转换工具**,支持两个转换方向:
|
||||
|
||||
| 转换方向 | 输入格式 | 输出格式 | 适用场景 |
|
||||
|---------|---------|---------|---------|
|
||||
| **方向1:分析格式** | 宽表 | 时间点→行,指标→列 | 统计分析、混合效应模型、GEE、数据可视化 |
|
||||
| **方向2:展示格式** | 宽表 | 时间点→列,指标→行 | 临床报告、数据审查表、CRF核对、单受试者数据审查 |
|
||||
|
||||
#### 2. 核心功能 ✅
|
||||
|
||||
**2.1 智能自动分组** ✅
|
||||
- ✅ 自动检测列名中的指标名称和时间点
|
||||
- ✅ 智能识别分隔符(`___`、`__`、`_`、`-`、`.`等)
|
||||
- ✅ 公共前缀智能扩展(修复"FMA总得分___基线"识别问题)
|
||||
- ✅ 时间点一致性验证
|
||||
- ✅ 置信度评分
|
||||
|
||||
**示例**:
|
||||
```
|
||||
输入列名:FMA总得分___筛选及基线、FMA总得分___随访(2周)、ADL总分___基线、ADL总分___随访(2周)
|
||||
自动检测:
|
||||
✓ 3个指标:FMA总得分、ADL总分、FM疗效
|
||||
✓ 8个时间点:筛选及基线、随访(2周)、随访(1个月)...
|
||||
✓ 分隔符:"___"
|
||||
```
|
||||
|
||||
**2.2 方向1:多指标转长表(时间点为行,指标为列)** ✅
|
||||
- ✅ 适用场景:R/Python统计分析、ggplot2/seaborn可视化、机器学习
|
||||
- ✅ 列顺序优化:`ID列 → Event_Name → 各指标列`
|
||||
- ✅ 保持原始Record ID顺序
|
||||
- ✅ 自动处理缺失值(outer join)
|
||||
|
||||
**示例**:
|
||||
```
|
||||
输入(宽表):
|
||||
Record_ID | FMA总得分_基线 | FMA总得分_随访1 | ADL总分_基线 | ADL总分_随访1
|
||||
4 | 58 | 67 | 40 | 95
|
||||
5 | 61 | 79 | 35 | 85
|
||||
|
||||
输出(长表):
|
||||
Record_ID | Event_Name | FMA总得分 | ADL总分
|
||||
4 | 基线 | 58 | 40
|
||||
4 | 随访1 | 67 | 95
|
||||
5 | 基线 | 61 | 35
|
||||
5 | 随访1 | 79 | 85
|
||||
```
|
||||
|
||||
**2.3 方向2:多指标转矩阵(时间点为列,指标为行)** ✅
|
||||
- ✅ 适用场景:临床报告、数据审查、CRF核对
|
||||
- ✅ 列顺序优化:`ID列 → 指标名列 → 各时间点列`
|
||||
- ✅ 保持原始Record ID顺序
|
||||
- ✅ 时间点列按原始顺序排列
|
||||
|
||||
**示例**:
|
||||
```
|
||||
输入(宽表):
|
||||
Record_ID | FMA总得分_基线 | FMA总得分_随访1 | ADL总分_基线 | ADL总分_随访1
|
||||
4 | 58 | 67 | 40 | 95
|
||||
|
||||
输出(矩阵):
|
||||
Record_ID | 指标名 | 基线 | 随访1
|
||||
4 | FMA总得分 | 58 | 67
|
||||
4 | ADL总分 | 40 | 95
|
||||
```
|
||||
|
||||
#### 3. UX优化 ✅
|
||||
|
||||
| 功能 | 说明 | 状态 |
|
||||
|------|------|------|
|
||||
| 转换方向选择 | Radio组件,两个选项,带场景说明 | ✅ |
|
||||
| 全选/清空按钮 | 快速选择所有值列 | ✅ |
|
||||
| 实时预览 | 选择列后自动生成预览(前10行) | ✅ |
|
||||
| 智能表单 | 根据转换方向动态显示不同的输入框 | ✅ |
|
||||
| 可视化分组结果 | Tag标签展示检测到的指标和时间点 | ✅ |
|
||||
| 置信度提示 | 检测置信度<1.0时显示警告 | ✅ |
|
||||
|
||||
#### 4. 技术架构 ✅
|
||||
|
||||
**4.1 Python层(`metric_time_transform.py`)**
|
||||
- ✅ `detect_metric_groups()` - 自动分组检测(300行)
|
||||
- ✅ `apply_multi_metric_to_long()` - 方向1转换(150行)
|
||||
- ✅ `apply_multi_metric_to_matrix()` - 方向2转换(180行)
|
||||
- ✅ 智能排序:保持原始Record ID顺序
|
||||
|
||||
**4.2 Python API(`main.py`)**
|
||||
- ✅ `POST /api/operations/multi-metric/detect` - 检测指标分组
|
||||
- ✅ `POST /api/operations/multi-metric/to-long` - 执行方向1转换
|
||||
- ✅ `POST /api/operations/multi-metric/to-matrix` - 执行方向2转换
|
||||
|
||||
**4.3 Node.js Backend**
|
||||
- ✅ `QuickActionService.ts` - 3个新方法
|
||||
- ✅ `QuickActionController.ts` - 支持2个新action
|
||||
- ✅ 路由注册:`/multi-metric/detect`
|
||||
|
||||
**4.4 Frontend(`MultiMetricPanel.tsx`)**
|
||||
- ✅ 转换方向选择(Radio组件)
|
||||
- ✅ 智能表单(动态显示)
|
||||
- ✅ 实时检测和预览
|
||||
- ✅ 完整的错误处理
|
||||
|
||||
#### 5. 关键技术突破 ✅
|
||||
|
||||
| 技术点 | 问题 | 解决方案 |
|
||||
|-------|------|---------|
|
||||
| 列名识别 | "FMA总得分___基线" 被错误识别为 "FMA" | 智能修正算法:扩展公共前缀 |
|
||||
| 列顺序 | Event_Name位置随机 | 强制列顺序:ID → Event_Name → 指标 |
|
||||
| Record ID顺序 | 转换后按字典序排序(4,10,11,5,6) | 添加临时列 `_original_order` 保持原始顺序 |
|
||||
| 分隔符识别 | 不支持三重下划线 `___` | 优先级列表:`['___', '__', '_', '-', '.']` |
|
||||
| 时间点提取 | `.lstrip()` 错误移除字符 | 使用 `.startswith()` 精确匹配 |
|
||||
|
||||
#### 6. 测试覆盖 ✅
|
||||
|
||||
| 测试场景 | 测试数据 | 状态 |
|
||||
|---------|---------|------|
|
||||
| 单ID列,多指标 | Record_ID: 4,5,6,10,11 | ✅ |
|
||||
| 三重下划线分隔符 | `FMA总得分___筛选及基线` | ✅ |
|
||||
| 括号时间点 | `随访(2周)` | ✅ |
|
||||
| 中文列名 | `FMA疗效` | ✅ |
|
||||
| 空值处理 | outer join保留所有时间点 | ✅ |
|
||||
| 原始顺序保持 | 4→5→6→10→11 | ✅ |
|
||||
|
||||
#### 7. 代码统计 ✅
|
||||
|
||||
| 文件 | 新增代码 | 说明 |
|
||||
|------|---------|------|
|
||||
| `metric_time_transform.py` | ~600行 | Python核心算法 |
|
||||
| `main.py` | ~150行 | 3个API端点 |
|
||||
| `QuickActionService.ts` | ~100行 | 3个新方法 |
|
||||
| `QuickActionController.ts` | ~50行 | Action支持 |
|
||||
| `MultiMetricPanel.tsx` | ~530行 | 完整UI组件 |
|
||||
| `TransformDialog.tsx` | ~30行 | Tab集成 |
|
||||
| **总计** | **~1460行** | **完整功能实现** |
|
||||
|
||||
---
|
||||
|
||||
### 🚀 Day 7-8 NA处理优化 + Pivot列顺序优化(2025-12-09~10)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# DC数据清洗整理模块 - 当前状态与开发指南
|
||||
|
||||
> **文档版本:** v3.2
|
||||
> **文档版本:** v3.3
|
||||
> **创建日期:** 2025-11-28
|
||||
> **维护者:** DC模块开发团队
|
||||
> **最后更新:** 2025-12-13 🏆 **Postgres-Only 架构改造完成!**
|
||||
> **重大里程碑:** Tool C MVP完成 + Tool B Postgres-Only架构改造(智能双模式、任务拆分、断点续传)
|
||||
> **最后更新:** 2025-12-21 ✨ **多指标转换功能上线!**
|
||||
> **重大里程碑:** Tool C MVP完成 + Tool B Postgres-Only架构改造 + **Tool C多指标转换(方向1+2)**
|
||||
> **文档目的:** 反映模块真实状态,记录开发历程
|
||||
|
||||
---
|
||||
@@ -67,17 +67,18 @@ DC数据清洗整理模块提供4个智能工具,帮助研究人员清洗、
|
||||
- ✅ 断点续传支持(支持长时间提取任务)
|
||||
- ✅ Platform层统一管理(job.data存储)
|
||||
- ✅ Worker注册(extractionWorker.ts)
|
||||
- ✅ **Tool C 完整实现**(2025-12-06 ~ 2025-12-10):
|
||||
- ✅ Python微服务(~1800行,Day 1 + NA处理优化 + 全量数据处理)
|
||||
- ✅ Node.js后端(~3500行,Day 2-3,Day 5-8增强 + 全量返回)
|
||||
- ✅ 前端界面(~4000行,Day 4-8,筛选/行号/滚动条/全量加载)
|
||||
- ✅ **Tool C 完整实现**(2025-12-06 ~ 2025-12-21):
|
||||
- ✅ Python微服务(~2400行,Day 1 + NA处理优化 + 全量数据处理 + 多指标转换)
|
||||
- ✅ Node.js后端(~3600行,Day 2-3,Day 5-8增强 + 全量返回 + 多指标转换)
|
||||
- ✅ 前端界面(~4500行,Day 4-8,筛选/行号/滚动条/全量加载 + 多指标转换)
|
||||
- ✅ **通用 Chat 组件**(~968行,Day 5)🎉
|
||||
- ✅ 7个功能按钮(Day 6)
|
||||
- ✅ NA处理优化(4个功能,Day 7)
|
||||
- ✅ Pivot列顺序优化(Day 7-8)
|
||||
- ✅ 计算列方案B(安全列名映射,Day 7-8)
|
||||
- ✅ **UX重大改进**(列头筛选/行号/滚动条修复/全量数据,Day 8)
|
||||
- **总计:~13068行** | **完成度:98%**
|
||||
- ✅ **多指标转换**(方向1+2,智能分组,原始顺序保持,Day 9)
|
||||
- **总计:~14528行** | **完成度:99%**
|
||||
- **重大成就**:
|
||||
- 🎉 **前端通用能力层建设完成**
|
||||
- ✨ 基于 Ant Design X 的 Chat 组件库
|
||||
|
||||
@@ -539,3 +539,9 @@ df['creatinine'] = pd.to_numeric(df['creatinine'], errors='coerce')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -377,3 +377,9 @@ npm run dev
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -954,3 +954,9 @@ export const aiController = new AIController();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1288,3 +1288,9 @@ npm install react-markdown
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -196,3 +196,9 @@ FMA___基线 | FMA___1个月 | FMA___2个月
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -354,3 +354,9 @@ formula = "FMA总分(0-100) / 100"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -188,3 +188,9 @@ async handleFillnaMice(request, reply) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -160,3 +160,9 @@ method: 'mean' | 'median' | 'mode' | 'constant' | 'ffill' | 'bfill'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -307,6 +307,12 @@ Changes:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -382,3 +382,9 @@ cd path; command
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -611,3 +611,9 @@ import { logger } from '../../../../common/logging/index.js';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -615,3 +615,9 @@ Content-Length: 45234
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -267,3 +267,9 @@ Response:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -420,3 +420,9 @@ Response:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -414,3 +414,9 @@ import { ChatContainer } from '@/shared/components/Chat';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -324,3 +324,9 @@ const initialMessages = defaultMessages.length > 0 ? defaultMessages : [{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -364,3 +364,9 @@ python main.py
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -612,3 +612,9 @@ http://localhost:5173/data-cleaning/tool-c
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -222,3 +222,9 @@ Day 5 (6-8小时):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -393,6 +393,12 @@ Docs: docs/03-业务模块/DC-数据清洗整理/06-开发记录/DC模块重建
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -372,6 +372,12 @@ const mockAssets: Asset[] = [
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -357,5 +357,11 @@ frontend-v2/src/modules/dc/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -316,6 +316,12 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -271,5 +271,11 @@ ConflictDetectionService // 冲突检测(字段级对比)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -320,5 +320,11 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -283,5 +283,11 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -347,5 +347,11 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -434,6 +434,12 @@ Tool B后端代码**100%复用**了平台通用能力层,无任何重复开发
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -281,5 +281,11 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -211,6 +211,12 @@ $ node scripts/check-dc-tables.mjs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -445,5 +445,11 @@ ${fields.map((f, i) => `${i + 1}. ${f.name}:${f.desc}`).join('\n')}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user