3、数据导入导出:CSV、Excel、数据库连接与操作
做药物知识图谱,数据来源五花八门。你拿到手的,可能是CSV表格、Excel报表,甚至是把数据库直接甩给你——“你自己连吧”。说白了,数据导入导出是R语言的第一道基本功。这一章,我带你过一遍最常见的三种数据源操作:CSV、Excel和数据库。每个坑我都踩过,你听我细说。
3.1 CSV文件:最通用的交换格式
CSV,逗号分隔值,说白了就是个文本文件。R自带的read.csv()和write.csv(),够用。但项目中我遇到过一个问题:药物名称里居然带逗号?比方说“阿司匹林,肠溶片”,一读进来就裂成两列,数据全乱了。
quote = "\""包裹,或者用readr::read_csv()——这个包会自动处理。
我个人习惯用data.table::fread(),速度是原生的10倍以上。尤其是几百万行的药物注册数据,fread几乎秒读。写法很简单:
library(data.table)
drugs <- fread("drugbank.csv", encoding = "UTF-8")
导出也一样:
fwrite(drugs, "drugbank_clean.csv")
| 函数 | 包 | 速度 | 适用场景 |
|---|---|---|---|
| read.csv() | base | 慢 | 小文件、一次性 |
| readr::read_csv() | readr | 中等 | 规范格式、带消息提示 |
| data.table::fread() | data.table | 快 | 大文件、自动识别分隔符 |
3.2 Excel文件:别被格式坑了
医药行业,Excel用得特别多。你要小心:多个Sheet、合并单元格、日期格式、科学计数法……. 我之前接过一个项目,同事把药物ATC代码存成Excel,结果“123456789012”直接变“1.23E+11”,气得我连夜写了个转换脚本。
R里推荐两个包:readxl和openxlsx。前者只读不写,轻量;后者能读写,支持样式。上代码:
library(readxl)
sheets <- excel_sheets("drug_atc.xlsx")
sheet1 <- read_excel("drug_atc.xlsx", sheet = 1)
# 指定列类型,避免数字变字符
sheet2 <- read_excel("drug_atc.xlsx", sheet = "ATC", col_types = c("text", "text", "numeric"))
read_excel()时,参数guess_max可以设置前N行用于类型猜测。如果前100行全是数字,第101行突然出现“N/A”,就全列变字符。我一般设guess_max = 2000。
写Excel,我习惯用openxlsx:
library(openxlsx)
wb <- createWorkbook()
addWorksheet(wb, "drugs")
writeData(wb, "drugs", drugs_df)
saveWorkbook(wb, "drug_output.xlsx", overwrite = TRUE)
3.3 数据库连接:从R直连 SQL
药物知识图谱的数据,很多时候存在关系型数据库里。比如药品说明书、不良反应报告、临床试验数据。你要做的,是从R里建连接、写SQL、拿结果。
主流方案:DBI + 对应数据库驱动。我拿MySQL举例:
library(DBI)
library(RMySQL)
con <- dbConnect(
MySQL(),
host = "localhost",
user = "root",
password = "your_password",
dbname = "drug_kg"
)
# 查询
result <- dbGetQuery(con, "SELECT * FROM drug_info WHERE atc_code LIKE 'A%'")
# 写入
dbWriteTable(con, "drug_filtered", result, overwrite = TRUE)
# 关闭
dbDisconnect(con)
还有odbc包,支持微软SQL Server、PostgreSQL。嗯,这个要提一句,如果你公司的数据库是SQL Server,用odbc连,驱动配置稍麻烦,但连上后都一样。
dbConnect()– 建立连接dbListTables()– 看有哪些表dbGetQuery()– 执行SQL并返回数据框dbWriteTable()– 把R数据框写入数据库dbDisconnect()– 用完必须关,不然连接池爆了
为什么会强调关连接?我曾经在批量建知识图谱关系时,开了100个连接没关,DBA直接打电话骂人……从那以后我都在on.exit()里写释放。
3.4 知识图谱导入场景:从文件到图数据库
你注意,本章讲的是“数据导入导出”,但最终目标是给知识图谱喂数据。通常流程是这样:
- 从CSV/Excel读取原始药物数据(药品名、ATC代码、适应症等)
- 清洗、合并、标注
- 写入关系型数据库或直接生成节点/边文件
- 用图数据库(Neo4j等)的
LOAD CSV命令导入
R在这里的角色就是“ETL管道”。你想想看,你手上几百万行的Excel,人工转成CSV再手动导入,效率太低了。R一条命令搞定。
openxlsx写20万行,爆内存了。最后换成fwrite写CSV,再fread读回去,稳得很。
3.5 避坑指南(我踩过的雷)
- 字符编码:Windows默认GBK,R读入后中文乱码。解决办法:
fread(encoding = "UTF-8"),或者先转成UTF-8再操作。 - 小数点分隔符:欧洲的CSV用逗号当小数点。记得
dec = ","。 - 数据库连接池:千万别在循环里反复
dbConnect和dbDisconnect。建一次连接,复用到底。 - Excel最大行数:Excel 2007+ 支持104万行,但
readxl不会报错,只会读取前几行?其实它会读全部。但文件本身超过200MB时,先剪切成多个Sheet再处理。