使用数据框中的值将函数应用于向量
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
是我需要的。
可能有一个简单的答案,但这是我尝试过的:首先,我创建了一个函数,如果通过收缩,该函数将 return 扩展版本:
expand <- function(contr) {
expd <- contractions[which(contractions[1]==contr),2]
}
我可以将 sapply
与此一起使用,它或多或少确实有效;在收缩的第一列上循环,sapply(contractions[,1],expand)
return 是一个命名的字符向量,带有扩展的短语。
虽然我不知道如何将这个向量与 gsub
结合起来。我尝试编写第二个函数 gsub_expand
并将扩展函数更改为 return 收缩和扩展:
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"
contractions 数据框中的第一个条目是 'cause 和 because,所以内部 sapply
似乎实际上并没有循环。我被困在我想传递给什么以及我应该循环什么的逻辑中。
感谢您的帮助。
两个选项:
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)
其中每一个都会return略有不同的无用数据,但也会将更改保存到vct2
,现在看起来与上面str_replace_all
的结果相同。
这些有点复杂,主要是因为您需要在每次更改时保存 vct
的内部版本。 vct <<-
写入初始化的 vct2
外部 函数环境,使我们能够捕获连续的变化。使用 <<-
时要小心一点;它很强大。有关详细信息,请参阅 ?assignOps
。
首先我要承认我在 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
是我需要的。
可能有一个简单的答案,但这是我尝试过的:首先,我创建了一个函数,如果通过收缩,该函数将 return 扩展版本:
expand <- function(contr) {
expd <- contractions[which(contractions[1]==contr),2]
}
我可以将 sapply
与此一起使用,它或多或少确实有效;在收缩的第一列上循环,sapply(contractions[,1],expand)
return 是一个命名的字符向量,带有扩展的短语。
虽然我不知道如何将这个向量与 gsub
结合起来。我尝试编写第二个函数 gsub_expand
并将扩展函数更改为 return 收缩和扩展:
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"
contractions 数据框中的第一个条目是 'cause 和 because,所以内部 sapply
似乎实际上并没有循环。我被困在我想传递给什么以及我应该循环什么的逻辑中。
感谢您的帮助。
两个选项:
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)
其中每一个都会return略有不同的无用数据,但也会将更改保存到vct2
,现在看起来与上面str_replace_all
的结果相同。
这些有点复杂,主要是因为您需要在每次更改时保存 vct
的内部版本。 vct <<-
写入初始化的 vct2
外部 函数环境,使我们能够捕获连续的变化。使用 <<-
时要小心一点;它很强大。有关详细信息,请参阅 ?assignOps
。