R语言tidyverse包无法安装_srt转word

编程文档 (71) 2023-03-24 15:01

问题来自头条文章:

Python Word文档转Excel

他们总说,R 语言处理文本数据、自动化办公不行,是真不行吗?本篇就来个 吊打 Python 看看。


1 问题描述

  • 有多个 word 文档:
R语言tidyverse包无法安装_srt转word_https://bianchenghao6.com/blog_编程文档_第1张

  • 文档内容:
R语言tidyverse包无法安装_srt转word_https://bianchenghao6.com/blog_编程文档_第2张

R语言tidyverse包无法安装_srt转word_https://bianchenghao6.com/blog_编程文档_第3张

  • 需求:

批量读取 word 文档内容,按名目:序号、方名、组成、用法、主治、备注,整理成 Excel 表格,结果如下:

R语言tidyverse包无法安装_srt转word_https://bianchenghao6.com/blog_编程文档_第4张

注:若未包含【组成】【用法】【主治】,则内容都归入备注。

2 解决问题

首先强调:文本数据处理,肯定离不开正则表达式!

  • 加载包
library(readtext)     # 读取文本数据
library(tidyverse)    # stringr, tidyr包, 处理文本数据
library(writexl)      # 写出到Excel
  • 批量读取 word 文档
df = readtext("word")     # 注意,word文档不能在打开状态
df
R语言tidyverse包无法安装_srt转word_https://bianchenghao6.com/blog_编程文档_第5张

得到的结果是数据框,每个文档占一行,doc_id 列是文件名,text 列是文档内容,一个文档内容整个是一个字符串。

  • 按药方切分列
df = df %>% 
  separate_rows(text, sep = "\n(?=\\d{5})")   # 切分标志是: \n五位数字序号
df
R语言tidyverse包无法安装_srt转word_https://bianchenghao6.com/blog_编程文档_第6张

此时,一个药方占一行了。

  • 解决一个药方的信息提取,写成函数
f = function(x) {
  tibble(
    序号 = str_extract(x, "^\\d{5}"),
    方名 = str_extract(x, "(?<=\\d·).*?(?=\n)"),
    组成 = str_extract(x, "(?<=【组成】).*?(?=\n【用法】|$)"),
    用法 = str_extract(x, "(?<=【用法】).*?(?=\n【主治】|$)"),
    主治 = str_extract(x, "(?<=【主治】).*?(?=\n|$)"),
    备注 = ifelse(str_detect(x, "【"), NA, str_extract(x, "(?<=\n).*#34;)))
}

说明:都是正则表达式提取,主要用到零宽断言,根据两端标志提取中间想要的内容。为什么看着这么啰嗦呢?是因为数据是有陷阱的:不是每个药方都包含【组成】、【用法】、【主治】,所以右端需要设置为下一项或结尾标志$

测试一个看看:

f(df$text[[1]])
R语言tidyverse包无法安装_srt转word_https://bianchenghao6.com/blog_编程文档_第7张

没问题!(我差点被对不齐给骗了)

  • 循环迭代,批量解决问题

就是把函数 f 依次应用到数据的 text列,结果按行合并:

rlt = map_dfr(df$text, f)
rlt
R语言tidyverse包无法安装_srt转word_https://bianchenghao6.com/blog_编程文档_第8张

  • 写出到 Excel 文件
write_xlsx(rlt, "结果表.xlsx")

结果就是问题描述中的结果表(略)。

问题解决!

以上是为了给大家展示中间过程,方便大家理解。拿掉不必要的中间过程,借助管道,完整代码如下:

library(readtext)     # 读取文本数据
library(tidyverse)    # stringr, tidyr包, 处理文本数据
library(writexl)      # 写出到Excel

df = readtext("word") %>% 
  separate_rows(text, sep = "\n(?=\\d{5})")

f = function(x) {
  tibble(
    序号 = str_extract(x, "^\\d{5}"),
    方名 = str_extract(x, "(?<=\\d·).*?(?=\n)"),
    组成 = str_extract(x, "(?<=【组成】).*?(?=\n【用法】|$)"),
    用法 = str_extract(x, "(?<=【用法】).*?(?=\n【主治】|$)"),
    主治 = str_extract(x, "(?<=【主治】).*?(?=\n|$)"),
    备注 = ifelse(str_detect(x, "【"), NA, str_extract(x, "(?<=\n).*#34;)))
}

map_dfr(df$text, f) %>% 
  write_xlsx("结果表.xlsx")

上一篇

已是最后文章

发表回复