【问题标题】:Use sapply/lapply or foreach to access data attributes R使用 sapply/lapply 或 foreach 访问数据属性 R
【发布时间】:2017-08-10 16:05:02
【问题描述】:

这可能是一个非常基本的问题,但老实说,我在这些类似问题上尝试了一些解决方案,但无法在我的数据上取得成功。可能是因为我的数据,或者我今天很辛苦,什么也想不通。 :(

我有一个句子向量

vec = c("having many items", "have an apple", "item")

另外,我有一个数据框来对数据进行词形还原

lem = data.frame(pattern = c("(items)|(item)", "(has)|(have)|(having)|(had)"), replacement = c("item", "have"))
lem$pattern = as.character(lem$pattern)
lem$replacement = as.character(lem$replacement)

我想遍历lem数据框中的每一行,形成一个替换命令。

选项 1:

library(stringr) #this is said to be quicker than gsub and my data has 3 mil sentences   
vec <- sapply(lem, function(x) str_replace_all(vec, pattern=x$pattern, replacement = x$replacement))

Error in x$pattern : $ operator is invalid for atomic vectors 

选项 2:

library(doPar)
vec <- foreach(i = 1:nrow(lem)) %dopar% {
str_replace_all(vec, pattern = lem[i, "pattern"], replacement = lem[i, "replacement"])
}

选项 2 返回 2 个向量的列表:第一个是我想要的,第二个是原始的,我不知道为什么。另外,我在我的机器上进行了测试,doPar(虽然使用并行编程)不如sapply 快。

由于我的数据很大(300 万句),有人可以推荐一种有效的方法来对文本数据进行词形还原吗?

【问题讨论】:

  • 如果您遍历lem 并将vec 中的每个元素替换为lem$pattern 中的每个元素,那么您最终会得到与lem 中的行一样多的结果,每个一个对应一个替换,这是您在 Option2 中观察到的。
  • 明白!我能做些什么来避免这种情况?
  • 我不熟悉doPar,但你可以简单地重写你的vec,如:for(i in 1:nrow(lem)){vec = str_replace_all(vec,lem$pattern[i],lem$replacement[i])}
  • 我不能使用顺序循环,Lamia。我的数据太大了。

标签: r nlp sapply parallel.foreach lemmatization


【解决方案1】:

另一种选择是从您的模式和替换向量而不是数据框创建一个命名向量,然后直接使用str_replace_all,如下所示:

library(stringr)

vec <- c("having many items", "has an apple", "items")

lem <- c("item", "have")
names(lem) <- c("(items)|(item)", "(has)|(have)|(having)|(had)")

str_replace_all(vec, lem)

## "have many item" "have an apple"  "item"

【讨论】:

  • 酷!我从未见过 str_replace_all 的这个选项。
  • lem 实际上是一个有两列的 *.csv 文件。通过使用这种技术,我想我需要转置数据框并使用pattern 列作为名称
  • 并非如此。从数据框中,您只需执行以下操作:lems &lt;- lem$replacementnames(lems) &lt;- lem$pattern,然后使用 lems 执行 str_replace_all 而不是 lem
  • 这不一定是我一直在寻找的解决方案,因为我热衷于寻找使用sapply (foreach) 的方法,但它解决了我的问题。它在 3 百万个数据点上运行得非常快。谢谢。
【解决方案2】:

您可以使用stringi 库中的stri_replace_all_regex,它将按顺序执行您的替换:

library(stringi)
stri_replace_all_regex(vec,lem$pattern,lem$replacement,vectorize_all=F)
[1] "have many item" "have an apple"  "item"

【讨论】:

  • 让我在我的数据集上尝试您的解决方案,看看它在性能方面的表现如何。不过,我更渴望有一个并行编程解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2015-10-15
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
相关资源
最近更新 更多