沿函数参数列表

时间:2017-11-06 12:24:29

标签: r functional-programming purrr

这是使用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)) 

非常感谢任何帮助或想法!

3 个答案:

答案 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"