在purrr::map中使用带有".$"的rsamples::bootstraps对象时出现问题。

问题描述 投票:1回答:1

很常见的是使用 %>% 运算符与 . 的左手边对象的表示。%>%比如说,。

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

但是使用 rsample::bootstraps() 函数来创建一个带有bootstrap-list-column的tibble,其中每个元素都有一个数据集,我发现使用 . 上面描述的模式,我不太明白。

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

有什么办法可以理解程序之间的这种行为吗?

r dplyr purrr tidymodels
1个回答
2
投票

这个问题其实并不是专门针对 rsample. 这只是如何 %>%magrittr 的作品。考虑到

mtcars %>% 
  mean(.$carb)

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

mean(mtcars, mtcars$carb)

默认情况下,管道总是会将你正在传输的内容放到函数的第一个参数中。你可以用 . 单独使用,但由于你在这里没有这样做,你仍然得到了传递给函数第一个参数的第一个对象以及一个额外的参数 .$samples 但是,这不符合签名的 map_dbl 你想使用的。这在以下情况下可以正常工作

mtcars %>% 
  split(.$cyl)

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

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)
                    })
© www.soinside.com 2019 - 2024. All rights reserved.