【问题标题】:Extracting speaker interventions from a text using R? Or something else?使用 R 从文本中提取说话者干预?或者是其他东西?
【发布时间】:2018-11-19 04:12:04
【问题描述】:

我们正在为学校开展一个文本挖掘项目,以了解魁北克国民议会中面向环境的演讲的比例。我们想提取多年来每位演讲者的发言清单。

我们的文档都是这样格式化的:

Mr. Smith : Blablabla

Mrs. Jones : Blablabla

我想做的是尽可能写出最简单的东西,让我能够提取这些干预。我的想法是这样的:

“每次您看到 [Mr. **** : ] 或 [Mrs. **** : ] 时,提取所有文本,直到您看到再次出现 [Mr. **** : ]或 [**** 夫人 : ]。理想情况下,将所有史密斯先生、琼斯夫人和威廉姆斯先生提取到单独的文件中,同时跟踪干预来自哪个文件。

我开始写一个非常基本的gsub 行,它允许我用@ 替换我想替换的事件,只是意识到我不想完全替换它们,而是可能只是添加一个@ front 这可能会使编写将 @s 分隔在不同文件中的内容变得更容易。

gsub("(Mr.|Mrs.)\\s\\w*\\s:\\s", "@", test)

我刚刚开始为这个项目自学 R,我需要一些关于下一步应该如何进行的见解。还是应该改用其他东西?

【问题讨论】:

  • 可能先标记单词然后cumsum(grepl(...)),就像这里的章节ID:tidytextmining.com/tidytext.html#tidyausten
  • 你能提供一个实际文档的链接吗?
  • “.”您在正则表达式中使用的实际上是元字符;作为元字符,它的意思不是“句号”而是“任何东西”。如果您确实想在正则表达式中包含句点作为句点,则必须将其转义:“\\.”

标签: r text-mining


【解决方案1】:

如果您不想替换演讲者姓名,可以使用所谓的“积极向前看”,如下所示:

# some example data:
bla <- c("Mr. X : blablabla bla bla bla. Mrs. Y : bla bla blablablab Mr. XY : bla bla balblabla blabl abl" )

# replace with look ahead:
gsub("(?=(Mr.|Mrs.))", "@ ", bla, perl = T)
"@ Mr. X : blablabla bla bla bla. @ Mrs. Y : bla bla blablablab @ Mr. XY : bla bla balblabla blabl abl"

@ 是提取个体干预的良好起点。可以这样做:

pattern <- "@.[^@]*" 
matches <- gregexpr(pattern, bla)
interventions <- regmatches(bla, matches)
interventions <- unlist(interventions)
interventions
[1] "@ Mr. X : blablabla bla bla bla. "      "@ Mrs. Y : bla bla blablablab "         "@ Mr. XY : bla bla balblabla blabl abl"

【讨论】:

  • 非常感谢,成功了!我必须在我的正则表达式上做一些工作,所以它只捕获了我需要的东西,但是你提取干预的行非常有效!现在我和我的同事可能会进行下一步,即将发言提取到每个发言者的单独文件中。我们会尝试自己找出答案,但如果您对我们应该如何进行有任何想法,请随时指导我们:)
  • 您可以这样继续: 1. 使用包stringrrequire(stringr) dat &lt;- data.frame( speaker_name = str_extract(interventions, "@.*[a-z|A-Z].*:"), intervention_text = str_extract(interventions, ":.*[a-z|A-Z].*") ) # 2. 删除“@”,将干预分成 2 列(1 用于发言者 ID,1 用于干预) & ":": dat$speaker_name &lt;- gsub("@ ", "", dat$speaker_name, perl = T) dat$intervention_text &lt;- gsub(": ", "", dat$intervention_text, perl = T) # 3.使用bydat拆分为每个不同ID的dfs:df_list &lt;- by(dat, dat$speaker_name, function(unique) unique) df_list
  • 第 2 步可以通过在第 1 步中使用正向后视来跳过。:dat &lt;- data.frame( speaker_name = str_extract(interventions, "(?&lt;=@).*[a-z|A-Z].*:"), # intervention_text = str_extract(interventions, "(?&lt;=:).*[a-z|A-Z].*") )
  • 在多次尝试错误之后,我选择了这个:require(stringr) dat &lt;- data.frame(speaker_name=str_extract(interventions, "((?&lt;=@)(.*?):)"), intervention_text=str_extract(interventions, "(?&lt;=:).*[a-z|A-Z].*")) df_list &lt;- by(dat, dat$speaker_name, function(unique) unique) 这几乎就是你给我的,除了为了只捕获第一个冒号,我必须改进正则表达式到这个((?&lt;=@)(.*?):),我改编自这个stackoverflow.com/a/42457235/10665396
  • 所以我认为你没事吧?或者有什么需要帮助的吗?
猜你喜欢
  • 1970-01-01
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-19
  • 1970-01-01
  • 2018-06-13
  • 2013-06-28
相关资源
最近更新 更多