[英]Using values from a dataframe to apply a function to a vector
首先,我承认我对R中的apply
函数和函数编写感到很糟糕。我正在研究一个课程项目,以清理和建模一些文本数据,并且我想包括一个步骤:清理宫缩。
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
。
可能有一个简单的答案,但这是我尝试的方法:首先,我创建了一个函数,如果传递了收缩,该函数将返回扩展版本:
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
似乎实际上并没有在循环。 我陷入了我想要传递给什么以及应该循环传递的逻辑的逻辑中。
谢谢你的帮助。
两种选择:
stringr::str_replace_all
stringr
程序包几乎可以执行与基本regex函数相同的操作,但有时以一种非常简单的方式进行。 这是那些时代之一。 您可以传递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
都将返回略有不同的无用数据,但是还将vct2
的更改保存到vct2
,该vct2
现在看起来与上述str_replace_all
的结果相同。
这些有点复杂,主要是因为每次进行更改时都需要保存vct
的内部版本。 vct <<-
在函数环境之外写入初始化的vct2
,使我们能够捕获连续的更改。 小心点<<-
; 它功能强大。 有关更多信息,请参见?assignOps
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.