如何使magrittr的管道操作符(%>%)在嵌套base-R函数时工作?

cczfrluj  于 2023-01-15  发布在  其他
关注(0)|答案(3)|浏览(129)

为什么这段代码会产生错误?

library(magrittr)

c('a', 'b', 'c', 'b') %>% 
  seq_len(length(.))

# Error in seq_len(., length(.)) : 
#   2 arguments passed to 'seq_len' which requires 1
crcmnpdw

crcmnpdw1#

另一种方法是用大括号括起来:

c('a', 'b', 'c', 'b') %>% 
  {seq_len(length(.))}

参见:https://magrittr.tidyverse.org/reference/pipe.html
通常,除了lhs本身的值之外,在rhs调用中还需要lhs的一些属性或特性,例如行数或列数。在rhs调用中多次使用点占位符是完全有效的,但在嵌套函数调用中使用它时,行为会略有不同。特别是,如果占位符仅在嵌套函数调用中使用,lhs也将被放置为第一个参数!这样做的原因是在大多数使用情况下,这会生成可读性最强的代码。例如,iris %〉% subset(1:nrow(.)%% 2 == 0)等效于iris %〉% subset(.,1:nrow(.)%% 2 == 0),但稍微更紧凑。可以通过将rhs括在大括号中来否决此行为。例如,1:10%〉% {c(min(.),max(.))}等效于c(min(1:10),max(1:10))。

wj8zmpe1

wj8zmpe12#

管道运算符尝试将左侧参数作为参数插入到右侧的函数调用中。如果您没有将rhs函数调用中的任何.用作参数,则默认情况下,它会将其作为第一个参数插入。在您的情况下,由于您没有将.直接用作seq_len的参数,因此它会将调用转换为:

seq_len(., length(.))

我认为筑巢是没有办法的。
然而,这里嵌套是没有意义的,管道操作符背后的主要思想是避免嵌套,所以更符合这种思想的代码应该是:

c('a', 'b', 'c', 'b') %>% 
  length() %>%
  seq_len()

编辑:我觉得我需要补充一下:你可以把.嵌套在其他调用中,但是你需要把.作为一个直接参数传递给rhs上的函数,至少一次。

1:5 %>%
  purrr::map2(., exp(.), ~ .x + .y) # first parameter is passes as a direct ., second is . nested within a call -- no implicit adding of . as first parameter
83qze16e

83qze16e3#

下面是一个使用匿名函数的解决方案

library(magrittr)

c('a', 'b', 'c', 'b') %>% 
  (\(.) seq_len(length(.)))

相关问题