r - 为什么在 dplyr 中使用 list() 对 .dots = setNames() 使用至关重要?

标签 r dplyr

我正在使用动态变量名称调用 mutate。一个最有效的例子是:

df <- data.frame(a = 1:5, b = 1:5)
func <- function(a,b){
  return(a+b)
}
var1 = 'a'
var2 = 'b'
expr <- interp(~func(x, y), x = as.name(var1), y = as.name(var2))
new_name <- "dynamically_created_name"
temp <- df %>% mutate_(.dots = setNames(expr, nm = new_name))

其中产生
temp
  a b func(a, b)
1 1 1          2
2 2 2          4
3 3 3          6
4 4 4          8
5 5 5         10

除了集合名称忽略了 nm 键之外,这通常很好。这是通过将我的函数包装在 list() 中来解决的:
temp <- df %>% mutate_(.dots = setNames(list(expr), nm = new_name))
temp
  a b dynamically_created_name
1 1 1                        2
2 2 2                        4
3 3 3                        6
4 4 4                        8
5 5 5                       10

我的问题是为什么 setNames 首先忽略它的关键,list() 如何解决这个问题?

最佳答案

other answer 中所述, .dots 参数被假定为一个列表,而 setNames 是一种重命名列表中元素的便捷方法。

.dots 参数在做什么?让我们先想想实际的点 ...争论。它是一系列要评估的表达式。圆点下方...是两个命名表达式 c = ~ a * scale1d = ~ a * scale2 .

scale1 <- -1
scale2 <- -2

df %>% 
  mutate_(c = ~ a * scale1, d = ~ a * scale2)
#>   a b  c   d
#> 1 1 1 -1  -2
#> 2 2 2 -2  -4
#> 3 3 3 -3  -6
#> 4 4 4 -4  -8
#> 5 5 5 -5 -10

我们可以预先将这些表达式捆绑在一个列表中。这就是 .dots 的用武之地。该参数让我们告诉 mutate_评估列表中的表达式。
bundled <- list(
  c2 = ~ a * scale1, 
  d2 = ~ a * scale2
)

df %>% 
  mutate_(.dots = bundled)
#>   a b c2  d2
#> 1 1 1 -1  -2
#> 2 2 2 -2  -4
#> 3 3 3 -3  -6
#> 4 4 4 -4  -8
#> 5 5 5 -5 -10

如果我们想以编程方式更新列表中表达式的名称,那么 setNames 是一种方便的方法。如果我们想在创建表达式时以编程方式混合和匹配常量和变量名称,那么lazyeval 包提供了方便的方法来做到这一点。下面我将创建一个表达式列表,命名它们,并使用 mutate_ 对它们进行评估。
# Imagine some dropdown boxes in a Shiny app, and this is what user requested
selected_func1 <- "min"
selected_func2 <- "max"
selected_var1 <- "a"
selected_var2 <- "b"

# Assemble expressions from those choices
bundled2 <- list(
  interp(~fun(x), fun = as.name(selected_func1), x = as.name(selected_var1)),
  interp(~fun(x), fun = as.name(selected_func2), x = as.name(selected_var2))
)
bundled2
#> [[1]]
#> ~min(a)
#> 
#> [[2]]
#> ~max(b)

# Create variable names
exp_name1 <- paste0(selected_func1, "_", selected_var1)
exp_name2 <- paste0(selected_func2, "_", selected_var2)

bundled2 <- setNames(bundled2, c(exp_name1, exp_name2))
bundled2
#> $min_a
#> ~min(a)
#> 
#> $max_b
#> ~max(b)

# Evaluate the expressions
df %>% 
  mutate_(.dots = bundled2)
#>   a b min_a max_b
#> 1 1 1     1     5
#> 2 2 2     1     5
#> 3 3 3     1     5
#> 4 4 4     1     5
#> 5 5 5     1     5

关于r - 为什么在 dplyr 中使用 list() 对 .dots = setNames() 使用至关重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36067533/

相关文章:

r - R 中 dplyr 中的 "Adding missing grouping variables"消息

r - 为什么R中的逻辑( boolean 值)需要4个字节?

r - 为什么 select.files() 不在当前工作目录中打开?

r - 跳过行直到具有特定值的行

r - 如何在 dplyr 中进行功能重命名?

r - 创建识别演讲者角色的列

r - 如何在 r 中落后 Quarters?

r - 如何在R中的不同表中找到相等的行?

r - 如何在 markdown/knitr 中的消息中换行?

mysql - 如何在 r 中执行 MySQL 更新查询