这是使用purrrr包的函数式编程问题。我确定如何表达这个问题,但一个简单的例子将展示我想要实现的目标。
我有一个字符串“ABCDEF”,我有一个列表列表,有正则表达式和替换匹配和替换:
subs = list(
A = list(regex = "A", sub = "a"),
B = list(regex = "B", sub = "b"),
C = list(regex = "C", sub = "c")
)
我想要做的是取字符串,然后一个接一个地应用stringr::str_replace_all
替换。
"ABCDEF" %>%
str_replace_all(subs$A$regex, subs$A$sub) %>%
str_replace_all(subs$B$regex, subs$B$sub) %>%
str_replace_all(subs$C$regex, subs$C$sub)
# "abcDEF"
我可以使用reduce
或其他更高阶函数的扩展吗?我知道这可以通过循环替换列表并在适当位置变换字符串来实现,但我正在寻找一个功能构造。
理想情况下会有一些高阶函数hof(.init, .x, .f, ...)
,这样我就可以递归地将一个函数应用到字符串中,如下所示:
hof(.init = "ABCDEF", .x = subs, ~ str_replace_all(.init, .x$regex, .x$sub))
非常感谢任何帮助或想法!
答案 0 :(得分:4)
我们可以使用for
循环并将每次迭代的输出分配给对象
for(i in seq_along(subs)) v1 <- str_replace_all(v1, subs[[i]]$regex, subs[[i]]$sub)
v1
#[1] "abcDEF"
正如@alexis_laz在评论中提到的那样purrr
类似的功能将是
library(purrr)
f1 <- function(x, args) str_replace_all(x, args$regex, args$sub)
reduce(.x = subs, .f = f1, .init = v1)
#[1] "abcDEF"
v1 <- "ABCDEF"
答案 1 :(得分:1)
你可以像你自己提到的那样使用Reduce
Reduce(function(l,r){str_replace_all(l,r$regex, r$sub)},subs,init = "ABCDEF")
答案 2 :(得分:1)
这是一种替代方法,它实际上不使用列表格式的模式和替换,但它将它们保存为向量,然后应用包mgsub
中的qdap
命令。
library(qdap)
library(purrr)
# list of patterns and replacements
subs = list(
A = list(regex = "A", sub = "a"),
B = list(regex = "B", sub = "b"),
C = list(regex = "C", sub = "c")
)
# get patterns and replacements as vectors from the list
subs_t = transpose(subs)
vec_pattern = unlist(subs_t$regex)
vec_replacement = unlist(subs_t$sub)
# apply function
mgsub(vec_pattern, vec_replacement, "ABCDEF")
# [1] "abcDEF"
# function also works with multiple texts
vec_text = c("ABCDEF", "FEDCBA")
mgsub(vec_pattern, vec_replacement, vec_text)
# [1] "abcDEF" "FEDcba"