最简R语言教程-数据处理通用流程

文档沟通和COSTAR提示词

R语言
文档沟通
ai提示词
COSTAR
数据处理
Author

Lee

Published

May 28, 2026

5步将凌乱的数据处理成干净的表格。

library(tidyverse)
library(skimr) # 数据概览
library(janitor)
library(naniar) # 处理缺失值

1 第一步:了解数据、快速诊断

1.1 基础诊断和了解

df <- read_csv("D:/Myblog/datas/P_data.txt") # 也可以读csv,看看哪个更干净

# ── 第一步:看数据结构 ────────────────────────────────
# 这行最重要,结果要粘给DeepSeek V4
glimpse(df)
Rows: 6
Columns: 8
$ `patient id`     <chr> "P001", "P002", "P003", "P004", "P005", "P006"
$ `admission date` <chr> "2023/3/15", "2023-04-02", "20230510", "2023/5/18", "…
$ age_year         <chr> "45", "62", "38", "-", "55", "71"
$ gender           <chr> "男", "女", "M", "女", "男", "女"
$ sbp_mmhg         <dbl> 128, 0, 136, 142, 118, 155
$ `glucose mg dL`  <chr> "148", "85", "0", "189", "不详", "201"
$ diagnosis        <chr> "糖尿病", "正常", "糖尿病前期", "糖尿病", "正常", "糖尿病"…
$ BMI              <dbl> 28.5, 26.1, 0.0, 31.2, 27.8, NA
# ── 第二步:详细描述统计 ──────────────────────────────
skim(df)
Data summary
Name df
Number of rows 6
Number of columns 8
_______________________
Column type frequency:
character 6
numeric 2
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
patient id 0 1 4 4 0 6 0
admission date 0 1 8 10 0 6 0
age_year 0 1 1 2 0 6 0
gender 0 1 1 1 0 3 0
glucose mg dL 0 1 1 3 0 6 0
diagnosis 0 1 2 5 0 3 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
sbp_mmhg 0 1.00 113.17 56.84 0 120.5 132.0 140.5 155.0 ▂▁▁▂▇
BMI 1 0.83 22.72 12.83 0 26.1 27.8 28.5 31.2 ▂▁▁▁▇
# ── 第三步:缺失值全貌 ────────────────────────────────
# 每列缺失值数量
colSums(is.na(df))
    patient id admission date       age_year         gender       sbp_mmhg 
             0              0              0              0              0 
 glucose mg dL      diagnosis            BMI 
             0              0              1 
# 可视化缺失值分布(一图看清楚)
vis_miss(df)

# ── 第四步:检查重复行 ────────────────────────────────
sum(duplicated(df))
[1] 0
df[duplicated(df), ] # 看具体是哪些重复行
# A tibble: 0 × 8
# ℹ 8 variables: patient id <chr>, admission date <chr>, age_year <chr>,
#   gender <chr>, sbp_mmhg <dbl>, glucose mg dL <chr>, diagnosis <chr>,
#   BMI <dbl>

1.2 把诊断结果给DeepSeek V4

将以上结果中的glimpse(df)复制粘贴给DeepSeek V4,提示它帮你分析数据质量问题,并给出处理建议。具体的COSTAR提示词吐下所示:

Tip使用COSTAR提示词分析数据质量问题

【C·背景】 我有一份[数据名称的]数据,glimpse输出如下:

[把 glimpse(df) 的完整输出粘贴在这里]

【O·目标】 1. 分析这份数据存在哪些数据质量问题, 2. 按类型归类(日期格式、缺失值、数据类型、编码不一致等), 3. 给出优先处理顺序

【S·风格】 条目式列出,每个问题说明:问题描述 + 可能的影响 + 建议处理方法

【T·语气】 专业简洁,直接给可操作的建议,不需要解释基础概念

【A·受众】 有R基础,想用AI辅助做数据分析

【R·格式】 按优先级排序的问题清单,最后给一个推荐的处理顺序

DeepSeek V4会帮我们梳理出一份”数据清洗任务清单”,按照这个清单来处理,不会漏掉任何问题。

2 第二步:处理缺失值-让数据不再”有病”

缺失值处理是数据清洗里最需要判断力的环节。不同情况用不同策略,没有万能方法。

Tip使用COSTAR提示词制定缺失值处理方案

我的数据缺失情况如下(百分比): [粘贴 missing_rate 的输出]

数据特点:替换为自己的数据特点 - 这是一份横断面临床研究数据,共[N]例 - 结局变量是[变量名](二分类) - 分析目的是做逻辑回归

【O·目标】 根据每个变量的缺失率和临床意义,给出具体的缺失值处理方案, 包括:处理策略选择、代码实现、处理后验证

【S·风格】tidyverse 风格,保守处理原则(宁可多删不误导)

【T·语气】生态环境科学研究规范,解释每个决策的统计学和依据

【A·受众】准备投稿SCI的生态环境科学研究者

【R·格式】 1. 每个变量的处理方案(表格形式) 2. 完整的处理代码 3. 敏感性分析建议

3 第三步:列名规范化-让代码不再认不出变量

  • 可使用janitor::clean_names()函数快速规范化列名,统一小写,去掉特殊字符,空格变下划线。但对中文列名可能不太友好,建议先用英文列名,或者后续再重命名。
  • 如果列不多,可以手动重命名,保持清晰有意义,避免过长或过短的名字。
  • 也可以使用COSTAR提示词让AI帮你生成规范的列名,尤其是当原始列名非常混乱时。
Tip使用COSTAR提示词生成规范列名

【C·背景】 我的R数据框有以下列名:

[粘贴 names(df) 的输出]

目标:转换为规范的英文小写下划线格式,变量名有实际含义

【O·目标】 生成一段 rename() 代码,把所有列名转换为规范的英文命名, 每个新列名后面加中文注释说明含义

【S·风格】tidyverse 管道写法

【R·格式】完整的 rename() 代码块,可以直接运行

4 第四步:数据类型转换-让每列数据都穿上合适的”衣服”

数据读进来之后,R 不一定能正确判断每列的类型。日期被读成字符串,分类变量被读成数字,数值被读成因子——这些都会导致后续分析出错。

Tip使用COSTAR提示词生成列类型转换代码

【C·背景】 数据框 df 的 glimpse 输出如下: [粘贴 glimpse(df) 输出]

存在以下类型问题:[替换为自己的数据问题] - date_admission 列是字符型,包含多种日期格式(举例说明) - gender 列编码不统一(列出具体值) - age 列是字符型(因为包含”-“)

【O·目标】 生成完整的数据类型转换代码,处理上述所有问题

【S·风格】tidyverse 管道写法,一个 mutate() 块完成所有转换

【T·语气】关键参数加注释解释为什么这样写

【R·格式】完整可运行代码 + 最后加验证代码(table/class/sum(is.na()))

5 第五步:数据验证——确认清洗结果符合预期

  1. 基础验证:检查数据清洗后的分布是否与原始数据一致,是否存在异常值或数据丢失问题。
  2. skimr 做数据质量报告:skimr::skim()函数是summary()的替代方案,可快速提供数据框的广泛概述。 它处理所有类型的数据,根据数据框中的列类型调度一组不同的摘要函数。
  3. 保存清洗后的数据。

6 实际应用

6.1 构建”脏”数据

set.seed(42) # 设置随机种子以保证结果可重现

# 构造第一张表:患者基本信息(patient_info)
# 包含:缺失值、重复行、数据类型错误、空格、格式不统一

# fmt: skip
patient_info <- tibble(
  patient_id = c(
    "P001", "P002", "P003", "P004", "P005",
    "P006", "P007", "P008", "P009", "P010",
    "P003", "P011", "P012" # P003 重复了
  ),
  name = c(
    "张三", " 李四", "王五 ", "赵六", NA, ## 注意李四前面和王五后面有空格,NA为缺失值
    "孙七", "周八", "吴九", "郑十", "王十一",
    "王五", "钱十二", " 陈十三 " # 王五重复,陈十三前后都有空格
  ),
  age = c(
    28, 35, -5, 42, 55, # -5 是不合理的年龄
    999, 38, NA, 31, 45, # 999 也不合理,还有一个 NA
    50, 67, 29
  ),
  gender = c(
    "M", "F", "Male", "F", "M", # Male 和 M 格式不统一
    "Female", "M", "f", "M", "F", # Female 和 F、f 和 F 不统一
    "M", "M", NA
  ),
  blood_pressure = c(
    "120/80", "130/85", "140/90", "NA", "125/82", # "NA" 是字符串,不是真缺失
    "135/88", "150", "128/84", "118/76", "132/86", # "150" 格式不对,缺少舒张压
    "140/92", "122/78", "126/80"
  ),
  admission_date = c(
    "2024-01-15", "2024/02/20", "20240310", # 三种日期格式混用
    "2024-04-05", "2024-05-12", "2024-06-08",
    "2024-07-22", "2024-08-15", "2024.09.03", # 又一种格式
    "2024-10-18", "2024-03-10", "2024-11-25",
    "2024-12-01"
  )
)

# 构造第二张表:实验室检查结果(lab_results)
# 包含:异常极端值、缺失值、ID 列名不同
# fmt: skip
lab_results <- tibble(
  ID = c(
    # 注意:这里列名叫 ID,不叫 patient_id
    "P001", "P002", "P003", "P004", "P005",
    "P006", "P007", "P008", "P009", "P010",
    "P013", "P014" # P013和P014 在 patient_info 里没有
  ),
  glucose = c(
    95, 110, 450, 88, NA, # 450 是极端异常值
    102, 97, 115, 0, 105, # 0 也不合理
    98, 108
  ),
  cholesterol = c(
    180, 220, 195, NA, 240,
    210, 185, -10, 200, 230, # -10 不合理
    175, 205
  ),
  hemoglobin = c(
    13.5, 12.8, NA, 14.2, 11.0, # 缺失值
    15.5, 99.9, 13.0, 12.5, 14.8, # 99.9 极端异常
    13.2, 11.8
  )
)

# 构造第三张表:随访记录(follow_up)
# 包含:一个患者多条记录、日期缺失
# fmt: skip
follow_up <- tibble(
  patient_id = c(
    "P001", "P001", "P002", "P003", "P004",
    "P005", "P005", "P005", "P006", "P015" # P015 在其他表里都没有
  ),
  visit_date = c(
    "2024-03-01", "2024-06-15", "2024-04-20", 
    NA, "2024-05-10", "2024-06-01", 
    "2024-09-15", "2024-12-20", 
    "2024-07-30", "2024-08-05"),
  status = c(
    "好转", "稳定", "好转", "恶化", "好转", 
    "稳定", "好转", "好转", "恶化", "失访")
)

6.2 缺失值处理