为单个列表映射

mapply for a single list

我理解 mapply(FUN, ...) 的用法,它循环遍历每个 ... 参数的元素并将 FUN 应用于这些组合。如果我将它们放在一个列表中而不是 ... 中的多个参数怎么办?

示例用例:
我定义了一个函数来粘贴不包括 NA:

的参数
pasteNotNA <- function(...,collapse=', '){
  dots <- list(...);
  paste(na.omit(unlist(dots)),collapse=collapse)
}

pasteNotNA('a',NA,'c')
# "a, c"

如果我将它们显式传递给 mapply:

,我可以将其逐元素应用于向量
mapply(pasteNotNA, c('a',NA,'c'),c('X','Y','Z'),c('1','2',NA),USE.NAMES = F)
# "a, X, 1"   "Y, 2"    "c, Z" 

我想要的是将它应用于列表并得到相同的结果:

inp_list <- list(vec1=c('a',NA,'c'), vec2=c('X','Y','Z'), vec3=c('1','2',NA))
some_apply(pasteNotNA, inp_list)
# "a, X, 1"   "Y, 2"    "c, Z"

我想这一定也是来自 *apply()Map() 家族的东西,但找不到好的解决方案...

1) 使用do.call :

do.call("mapply", c(pasteNotNA, inp_list, USE.NAMES = FALSE))
## [1] "a, X, 1" "Y, 2"    "c, Z"  

2) 或者使用 purrr 包中的 pmap_chr:

library(purrr)

pmap_chr(inp_list, pasteNotNA)
## [1] "a, X, 1" "Y, 2"    "c, Z"   

3) 这也有效:

apply(as.data.frame(inp_list), 1, pasteNotNA)
## [1] "a, X, 1" "Y, 2"    "c, Z"   

我们可以使用 unite,它已经有 na.rm 个参数

library(tidyr)
library(dplyr)
as_tibble(inp_list) %>% 
  unite(vec, everything(), na.rm = TRUE, sep =", ")
# A tibble: 3 × 1
  vec    
  <chr>  
1 a, X, 1
2 Y, 2   
3 c, Z