我首先承认我在apply
函数中表现得非常糟糕,并且在R中一般都是函数编写。我正在开设一个课程项目来清理和建模一些文本数据,我想包括一个清理收缩的步骤。
qdapDictionaries
包中包含一个contractions
数据框,其中包含两列,第一列是收缩,第二列是扩展版本。例如:
contraction expanded
5 aren't are not
我想使用这里的值在我的文本上运行gsub
函数,我仍然在一个大字符元素中。类似于gsub(contr,expd,text)
。
这是我用来测试的示例向量:
vct <- c("I've got a problem","it shouldn't be that hard","I'm having trouble 'cause I'm dumb")
我很难理解如何循环数据框(没有实际编写循环,因为它似乎是效率最低的方式)因此我可以运行所有gsub
s需要。
这可能是一个简单的答案,但这是我尝试过的:首先,我创建了一个函数,如果通过收缩,它将返回扩展版本:
expand <- function(contr) {
expd <- contractions[which(contractions[1]==contr),2]
}
我可以使用sapply
,它可以或多或少地起作用;在收缩中循环第一列,sapply(contractions[,1],expand)
返回带有扩展短语的命名矢量字符。
我无法弄清楚如何将此向量与gsub
结合起来。我尝试编写第二个函数gsub_expand
并更改expand函数以返回收缩和扩展:
gsub_expand <- function(list, text) {
text <- gsub(list[[1]],list[[2]],text)
return(text)
}
当我跑gsub_expand(sapply(contractions[,1],expand),vct)
时,它只纠正了我的一部分矢量。
[1] "I've got a problem" "it shouldn't be that hard" "I'm having trouble because I'm dumb"
收缩数据框中的第一个条目是因为因为内部sapply
似乎实际上没有循环。我陷入了我想要传递给什么的逻辑,以及我应该绕过的东西。
感谢您的帮助。
答案 0 :(得分:1)
两个选项:
stringr::str_replace_all
stringr
包与基本正则表达式函数大致相同,但有时候会以极其简单的方式执行。这是其中一次。您可以传递str_replace_all
命名列表或字符向量,它将使用名称作为模式,将值用作替换,因此您只需要
library(stringr)
contractions <- c("I've" = 'I have', "shouldn't" = 'should not', "I'm" = 'I am')
str_replace_all(vct, contractions)
你得到了
[1] "I have got a problem" "it should not be that hard"
[3] "I am having trouble 'cause I am dumb"
没有麻烦,没有大惊小怪,只是工作。
lapply
/ mapply
/ Map
和gsub
您当然可以使用lapply
或for
循环来重复gsub
。您可以通过几种方式制定此调用,具体取决于数据的存储方式以及您希望如何获取数据。让我们先复制vct
,因为我们要覆盖它:
vct2 <- vct
现在我们可以使用以下三种中的任何一种:
lapply(1:length(contractions),
function(x){vct2 <<- gsub(names(contractions[x]), contractions[x], vct2)})
# `mapply` is a multivariate version of `sapply`
mapply(function(x, y){vct2 <<- gsub(x, y, vct2)}, names(contractions), contractions)
# `Map` is a multivariate version of `lapply`
Map(function(x, y){vct2 <<- gsub(x, y, vct2)}, names(contractions), contractions)
每个都会返回略有不同的无用数据,但也会将更改保存到vct2
,现在看起来与上面str_replace_all
的结果相同。
这些有点复杂,主要是因为您需要在每次更改时保存vct
的内部版本。 vct <<-
写入函数环境外的初始化vct2
,允许我们捕获连续的更改。对<<-
要小心一点;它很强大。有关详细信息,请参阅?assignOps
。