新的本地管道占位符究竟是如何工作的?

How does the new native pipe placeholder works, exactly?

我不明白新的本地管道占位符是如何工作的。在 R 4.2 之前,本地管道没有占位符,因此您需要创建一个专用的匿名函数,以便将管道对象传递给第一个函数参数以外的函数参数。现在,在 R 4.2 发布后,本地管道也有了一个专用的占位符 _。我还知道这个新的占位符只有在直接声明将接收占位符的参数名称时才有效:R 4.2.0 Native Placeholder。但是我仍然面临一些麻烦,无法完全理解如何实现它。

我举个例子。我写了一个简单的管道代码块,它接受一个对象和 returns 每列中有多少缺失值。

x = c(NA, NA, 1, NA, 1, 2)
m = matrix(x, nrow = 3, ncol = 2)
m

#      [,1] [,2]
# [1,]   NA   NA
# [2,]   NA    1
# [3,]    1    2


#### CHECK FOR MISSING VALUES ####
m |> 
  { \(.) .colSums(is.na(.), NROW(.), NCOL(.)) }() |> 
  { \(sum.NA) rbind(names(m), sum.NA) }() |> 
  t()

#      sum.NA
# [1,]      2
# [2,]      1

前面的代码使用了匿名函数的方法,效果很好。我无法将此代码更改为正确使用新的占位符。你有什么建议吗?

占位符是在 .来自 R News, CHANGES IN R 4.2.0,部分 NEW FEATURES,我的重点。

  • In a forward pipe |> expression it is now possible to use a named argument with the placeholder _ in the rhs call to specify where the lhs is to be inserted. The placeholder can only appear once on the rhs.

您只能在 rhs 命名参数中使用一次占位符。

虽然问题中链接到的博客 post 提到了命名参数义务并给出了正确和 错误 使用占位符的方法,但它没有提到它只能使用一次。


在问题的情况下,不需要使用新的占位符 _

x = c(NA, NA, 1, NA, 1, 2)
m = matrix(x, nrow = 3, ncol = 2)
m
#>      [,1] [,2]
#> [1,]   NA   NA
#> [2,]   NA    1
#> [3,]    1    2

m |>
  is.na() |>
  colSums() |>
  matrix(dimnames = list(NULL, 'sum.NA'))
#>      sum.NA
#> [1,]      2
#> [2,]      1

reprex package (v2.0.1)

创建于 2022-06-02

另一种方式,每步一个函数,这次使用占位符。
(看了才想起来用cbind。)

m |>
  is.na() |>
  colSums() |>
  cbind(sum.NA = _)
#>      sum.NA
#> [1,]      2
#> [2,]      1

reprex package (v2.0.1)

创建于 2022-06-02

您需要稍微重组一下才能利用 _ 。 _ 没有直接解决在RHS上多次使用LHS的问题,也没有解决在RHS上嵌套函数的问题,这两个都是代码面临的问题。另请注意,问题中的代码在代码中再次使用了 m,这确实打败了从左到右的管道概念。 names(m) 也为 NULL,因为 m 没有名字。

我们创建一个包含名为 x 的单个元素的列表,然后在下一行中使用它来解决必须引用它 3 次的问题,并解决嵌套调用问题。在 rbind 中,我们消除了对 m 的引用,因为 rbinding NULL 毫无意义。我们确实设法使用了 _ 两次并消除了所有匿名函数,同时主要保持问题中代码的想法。

m |>
  list(x = _) |>
  with(.colSums(is.na(x), NROW(x), NCOL(x))) |>
  rbind(sum.NA = _) |>
  t()