首页 > 解决方案 > mutate_at 中的复合函数

问题描述

我有一个小标题:

df = tibble(one = list('a', 'b'), two = list(c('p1', 'p2', 'p3'), NA_character_), three = list(NA_character_, c('z1', 'z2', 'z3')))

df
# A tibble: 2 x 3
  one   two       three    
  <chr> <list>    <list>   
1 a     <chr [3]> <chr [1]>
2 b     <chr [1]> <chr [3]>

我想将列中的缺失值替换为two使用列的three值,然后使用. 我的预期输出如下所示:onecoalesce()twothreetoString()

df = tibble(one = c('a', 'b'), two = list('p1, p2, p3', 'b'), three = list('a', 'z1, z2, z3'))
df
# A tibble: 2 x 3
  one   two       three    
  <chr> <list>    <list>   
1 a     <chr [1]> <chr [1]>
2 b     <chr [1]> <chr [1]>

这是我最初尝试过的:

df %>% mutate_at(vars(two, three), funs(coalesce(., one) %>% map(., toString)))

我知道funs()引用了它的论点,但我不明白为什么它不适用于管道。该文档还建议funs不推荐使用它,但我不确定在它的位置使用什么。我想知道是否有人可以解释为什么上面的方法不起作用,因为我完全不熟悉作用域动词的内部工作原理。

标签: rdata-manipulationpurrrdplyr

解决方案


我们可以使用map2,使用coalesce然后toString

library(dplyr)
library(purrr)

df1 <- df %>% 
        mutate_at(vars(two, three), ~map2(., one, ~toString(coalesce(.x, .y))))

df1

#  one   two       three    
#  <chr> <list>    <list>   
#1 a     <chr [1]> <chr [1]>
#2 b     <chr [1]> <chr [1]>

df1$two
#[[1]]
#[1] "p1, p2, p3"

#[[2]]
#[1] "b"

df1$three
#[[1]]
#[1] "a"

#[[2]]
#[1] "z1, z2, z3"

在上面的示例中,我们使用 lambda 样式表达式 using~将其用作函数,并且它是 truefuns已被弃用并已被替换为list()此问题中的答案和评论提供了对此的更多见解。


推荐阅读