向mutate_at传入单个变量时表现同mutate,是Bug还是使用错误?
关于
mutate_at传入单个变量时的行为解释 这完全是预期之内的设计,不是Bug哦!mutate_at作为dplyr里的批量变量处理工具,核心逻辑就是对你指定的一组变量逐一应用函数操作——当你给它多个变量时,它就批量生成对应新列;当你只给它一个变量时,自然就只处理这一个变量,结果看起来和直接用mutate单独操作该变量一致,但这可不是“退化”,只是它在单变量场景下的正常工作模式而已。
咱们用你的代码实际跑一遍,就能看清楚规律:
library("tidyverse") x <- data_frame("a" = 1:3, "b" = 4:6) f <- function(y){2L * y} # 多变量场景:为每个变量生成带后缀的新列 x %>% mutate_at(vars(c("a", "b")), funs(x = f)) #> # A tibble: 3 × 4 #> a b a_x b_x #> <int> <int> <int> <int> #> 1 1 4 2 8 #> 2 2 5 4 10 #> 3 3 6 6 12 # 单变量场景(直接传字符向量):只生成对应变量的新列 x %>% mutate_at(c("a"), funs(x = f)) #> # A tibble: 3 × 3 #> a b a_x #> <int> <int> <int> #> 1 1 4 2 #> 2 2 5 4 #> 3 3 6 6 # 单变量场景(用vars包裹):效果和上面完全一致 x %>% mutate_at(vars(c("a")), funs(x = f)) #> # A tibble: 3 × 3 #> a b a_x #> <int> <int> <int> #> 1 1 4 2 #> 2 2 5 4 #> 3 3 6 6 # 重复传入同一变量两次:会生成带序号后缀的多个新列 x %>% mutate_at(vars(c("a", "a")), funs(x = f)) #> # A tibble: 3 × 4 #> a b a_x a_x1 #> <int> <int> <int> <int> #> 1 1 4 2 2 #> 2 2 5 4 4 #> 3 3 6 6 6 x %>% mutate_at(c("a", "a"), funs(x = f)) #> # A tibble: 3 × 4 #> a b a_x a_x1 #> <int> <int> <int> <int> #> 1 1 4 2 2 #> 2 2 5 4 4 #> 3 3 6 6 6
关键结论:
- 多变量输入时:
mutate_at会遍历每个变量生成对应新列,这是它的核心批量处理能力; - 单变量输入时:它只处理这一个变量,结果和
mutate(a_x = f(a))一致,但这是正常的单变量批量处理(虽然“批量”变成了“单个”); - 重复变量输入时:它会为每次应用生成带序号的新列,这也能看出它本质还是在做批量遍历的逻辑。
另外提一句:在新版dplyr里,funs()已经被推荐用list()替代啦,比如上面的funs(x = f)可以写成list(x = f),功能完全一样,语法更清晰。
内容的提问来源于stack exchange,提问作者David de Wit
相关产品推荐
相关产品推荐

