dplyr::mutate 内带有基本 R 管道的“管道占位符的无效使用”

Gil*_*les 4 r dplyr

为什么这个带有基本 R 管道和占位符的命令dplyr::mutate会返回错误消息?

library(dplyr)
iris[,-5] |> mutate(Row_sum = apply(X = _, 1, function(x) sum(x)))

#> Error in mutate(iris[, -5], Row_sum = apply(X = "_", 1, function(x) sum(x))) : 
#> invalid use of pipe placeholder
Run Code Online (Sandbox Code Playgroud)

在 mutate 之外工作正常:

iris[,-5] |> apply(X = _, 1, function(x) sum(x))

#>   [1] 10.2  9.5  9.4  9.4 10.2 11.4  9.7 10.1  8.9  9.6 10.8 10.0  9.3  8.5 11.2
#>  [16] 12.0 11.0 10.3 11.5 10.7 10.7 10.7  9.4 10.6 10.3  9.8 10.4 10.4 10.2  9.7
#>  [31]  (...)
Run Code Online (Sandbox Code Playgroud)

使用 magrittr 管道在 mutate 内部工作正常

iris[,-5] %>% mutate(Row_sum = apply(X = ., 1, function(x) sum(x))) %>% head

#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Row_sum
#> 1          5.1         3.5          1.4         0.2    10.2
#> 2          4.9         3.0          1.4         0.2     9.5
#> 3          4.7         3.2          1.3         0.2     9.4
#> 4          4.6         3.1          1.5         0.2     9.4
#> 5          5.0         3.6          1.4         0.2    10.2
#> 6          5.4         3.9          1.7         0.4    11.4
Run Code Online (Sandbox Code Playgroud)

MrF*_*ick 10

问题是使用嵌套函数调用时不能使用_with 。|>例如第一个有效,第二个无效

5 |> log()
# [1] 1.609438
5 |> log(exp(_))
# Error in log(5, exp("_")) : invalid use of pipe placeholder
Run Code Online (Sandbox Code Playgroud)

请注意,|>with与本例中的with_略有不同。如果将with用作表达式的一部分,则完整的管道对象仍作为第一个参数传递给函数。所以你基本上把它包含了两次。对于和,这种情况永远不会发生。例如%>%..%>%|>_

iris %>% split(.$Species)
Run Code Online (Sandbox Code Playgroud)

有效,因为它与

split(iris, iris$Species)
Run Code Online (Sandbox Code Playgroud)

请注意,虹膜基本上包含两次。但这不适用于新的管道运算符

iris |> split(_$Species)
# Error in split(iris, "_"$Species) : invalid use of pipe placeholder
Run Code Online (Sandbox Code Playgroud)

因为它基本上是一个嵌套函数调用($计数为函数调用)。split这就是他们现在同时更新为使用公式的原因之一。所以这会起作用

iris |> split(~Species)
Run Code Online (Sandbox Code Playgroud)

如果您只想添加行总和而不添加第五列,您可以这样做

iris |>
    mutate(Row_sums=rowSums(across(-5)))
# or
iris[, -5]|>
    mutate(Row_sums=rowSums(across(everything())))
Run Code Online (Sandbox Code Playgroud)

  • @Gilles我强烈建议避免在 data.frame 中使用“apply”,如果您有混合数据类型,它可能会导致很多问题,因为它在运行函数之前将所有内容强制转换为矩阵。如果你想跨列使用任意函数,那么更 dplyr 的方法是使用 `rowwise()` 和 `c_across()`: `iris |> rowwise() |> mutate(SD=sd(c_across(- 5)))` (2认同)