r-使用pmap将不同的正则表达式应用于tibble中的不同变量



我正在尝试将不同的正则表达式应用于tibble中的不同变量。例如,我制作了一个tibble列表:1(我想要修改的变量名,2(我想要匹配的正则表达式,以及3(替换字符串。我想将regex/replacement应用于不同数据帧中的变量。

所以我的"配置"tibble看起来是这样的:

test_config <-  dplyr::tibble(
string_col = c("col1", "col2", "col3", "col4"),
pattern = c("^\.$", "^NA$", "^NULL$", "^$"),
replacement = c("","","", "")
)

我想把它应用到一个目标上:

test_target <- dplyr::tibble(
col1 = c("Foo", "bar", ".", "NA", "NULL"),
col2 = c("Foo", "bar", ".", "NA", "NULL"),
col3 = c("Foo", "bar", ".", "NA", "NULL"),
col4 = c("NULL", "NA", "Foo", ".", "bar")
)

因此,目标是在test_target的每个列/变量中用空字符串替换不同的字符串。

结果应该是这样的:

result <- dplyr::tibble(
col1 = c("Foo", "bar", "", "NA", "NULL"),
col2 = c("Foo", "bar", ".", "", "NULL"),
col3 = c("Foo", "bar", ".", "NA", ""),
col4 = c("NULL", "NA", "Foo", ".", "bar")
)

我可以用for循环做我想做的事情,比如这样:

for (i in seq(nrow(test_config))) {
test_target <- dplyr::mutate_at(test_target,
.vars = dplyr::vars(
tidyselect::matches(test_config$string_col[[i]])),
.funs = dplyr::funs(
stringr::str_replace_all(
., test_config$pattern[[i]], 
test_config$replacement[[i]]))
)
}

相反,有没有一种更整洁的方式来做我想做的事?到目前为止,我认为purrr::pmap是这项工作的工具,我已经制作了一个函数,它接受数据帧、变量名、正则表达式和替换值,并返回修改了单个变量的数据帧。它的行为如预期:

testFun <- function(df, colName, regex, repVal){
colName <- dplyr::enquo(colName)
df <- dplyr::mutate_at(df,
.vars = dplyr::vars(
tidyselect::matches(!!colName)),
.funs = dplyr::funs(
stringr::str_replace_all(., regex, repVal))
)
}
# try with example
out <- testFun(test_target, 
test_config$string_col[[1]], 
test_config$pattern[[1]], 
"")

然而,当我尝试将该函数与pmap一起使用时,我遇到了几个问题:1( 有比这更好的方法来建立pmap调用的列表吗?

purrr::pmap(
list(test_target, 
test_config$string_col, 
test_config$pattern, 
test_config$replacement),
testFun
)

2( 当我调用pmap时,我得到一个错误:

Error in UseMethod("tbl_vars") : 
no applicable method for 'tbl_vars' applied to an object of class "character"
Called from: tbl_vars(tbl)

你们中的任何人能建议一种使用pmap来做我想做的事情的方法吗?或者有没有一种不同或更好的方法来解决这个问题?

谢谢!

使用map2_dfc的另一种方法(_dfc后缀也可用于pmap(:

library(dplyr)
library(purrr)
map2_dfc(test_target, seq_along(test_target), 
~sub(test_config$pattern[.y], 
test_config$replacement[.y], .x))

imap_dfc(注意,这样会丢失列名(:

imap_dfc(unname(test_target), 
~sub(test_config$pattern[.y], 
test_config$replacement[.y], .x))

输出:

# A tibble: 5 x 4
col1  col2  col3  col4 
<chr> <chr> <chr> <chr>
1 Foo   Foo   Foo   NULL 
2 bar   bar   bar   NA   
3 ""    .     .     Foo  
4 NA    ""    NA    .    
5 NULL  NULL  ""    bar 

您不需要创建函数(您的函数实际上是问题的根源(:您可以直接使用str_replace_all

pmap_dfr(
list(test_target,
test_config$pattern,
test_config$replacement),
str_replace_all
)
# A tibble: 5 x 4
col1  col2  col3  col4 
<chr> <chr> <chr> <chr>
1 Foo   Foo   Foo   NULL 
2 bar   bar   bar   NA   
3 ""    .     .     Foo  
4 NA    ""    NA    .    
5 NULL  NULL  ""    bar  

最新更新