1

%>%将运算符与.的左侧(LHS)对象结合使用是很常见的%>%,例如:

library(purrr)
mtcars %>% 
  split(.$cyl) %>%    # as you can see here
  map(~ lm(mpg ~ hp, data = .x))

但是使用rsample::bootstraps()函数创建一个带有引导列表列的小标题,其中每个元素都有一个数据集,我注意到使用.上面描述的模式时出现错误,我不太理解。

library(purrr)
# create a 3 partitions

# inspect how many cyl == 4 are in each partition (ERROR)
rsample::bootstraps(mtcars, times = 3) %>%
map_dbl(.$splits,
        function(x) {
                     cyl = as.data.frame(x)$cyl
                     mean(cyl == 4)
                    })
Error: Index 1 must have length 1, not 4
Run `rlang::last_error()` to see where the error occurred.

但是,如果您将 的输出存储rsample::bootstraps()ex对象中然后使用map_dbl,正如您在文档中看到的那样,它可以正常工作。

library(purrr)
# create 3 partitions
ex <- rsample::bootstraps(mtcars, times = 3)

# inspect how many cyl == 4 are in each partition (WORKS OK)
map_dbl(ex$splits,
        function(x) {
                     cyl = as.data.frame(x)$cyl
                     mean(cyl == 4)
                    })
 [1] 0.50000 0.28125 0.43750

了解程序之间的这种行为有什么想法吗?

4

1 回答 1

2

问题并不是真正特定于rsample. 这就是%>%from 的magrittr工作原理。考虑

mtcars %>% 
  mean(.$carb)

这也会导致错误。因为它基本上调用的是

mean(mtcars, mtcars$carb)

默认情况下,管道将始终将您正在管道中的内容放置到函数的第一个参数中。您可以将其.单独移动到不同的参数,但由于您没有在此处执行此操作,因此您仍然会将整个第一个对象与另一个参数一起传递给函数的第一个参数,.$samples但与签名不匹配map_dbl你想使用的那个。这适用于

mtcars %>% 
  split(.$cyl)

因为split()期望整个 data.frame 作为第一个参数。split 的正确调用是

split(mtcars, mtcars$cyl)

一直以来,如果您不想为您填充第一个参数,则可以改为通过管道输入块{}

你可以做

rsample::bootstraps(mtcars, times = 3) %>%
{map_dbl(.$splits,
        function(x) {
                     cyl = as.data.frame(x)$cyl
                     mean(cyl == 4)
                    })}

或者你可以pull明确地列

rsample::bootstraps(mtcars, times = 3) %>%
  dplyr::pull(splits) %>%
  map_dbl(
        function(x) {
                     cyl = as.data.frame(x)$cyl
                     mean(cyl == 4)
                    })
于 2020-05-18T19:58:30.153 回答