-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add custom type for pin_write()
#649
Conversation
I played around with a few ideas today, hoping each time to arrive at something simpler. I still need to add tests, and more-complete documentation, but I wanted to run this proposed approach past you: I am impressed with what you can do using
It has to be a function that takes the object first, then the path second. The larger question seems to be the interaction between
Here's what I propose for behavior:
Notes:
I'll start working on tests, etc., but wanted to give you an early chance to react. Thanks! |
I think this is looking promising, but that table you made had me realize that we are probably bumping up against argument dependencies/interdependence. This has absolutely been a headache for me before 😩 so we definitely want to avoid this pattern if possible. What do you think about adding support for passing a function to |
I am with you. I now appreciate the danger of argument dependencies, thanks for helping me learn new things! I will be happy to revise things to use the
|
This reverts commit be6e2a1.
Pondering this a bit more, there already exists the Overloading the very_important_data <-
pin_download(my_board, "my-custom-pin") |>
custom_reader_function() |
I have run into another problem: how to specify the file extension. In One possible solution might be to offer a helper function, #' @param f `function` that takes the object and a path, then writes the object to the path.
#' @param extension `character` extension for the file to be written.
#'
pin_file_writer <- function(.f, extension) {
.f <- rlang::as_function(f)
function(x, name = NULL) {
# determine name, if needed
if (is.null(name)) {
name <- enexpr(x)
if (is_symbol(name)) {
name <- as.character(name)
pins_inform("Using `name = '{name}'`")
} else {
abort("Must supply `name` when `x` is an expression")
}
}
# determine path for file
path <- fs::path_temp(fs::path_ext_set(fs::path_file(name), extension))
# write object to file
.f(x, path)
# delete file when environment that called writer is destroyed
withr::defer(fs::file_delete(path), envir = parent.frame())
invisible(path)
}
} arrow_pin_writer <- pin_file_writer(
\(x, path) arrow::write_feather(x, path, compression = "uncompressed"),
extension = "arrow"
)
pin_write(my_board, x = mtcars, type = arrow_pin_writer) Alternatively (if I'm understanding the code correctly): pin_upload(my_board, paths = arrow_pin_writer(mtcars)) If using I am sorry that I have turned this into a ride on the "API merry-go-round". While I enjoy an API discussion as much as (perhaps more than) the next person, I know you all have other things to do. I'll start coding in this direction unless or until I hear otherwise :) |
I think I have something minimally working; here's what I get: library("pins")
arrow_pin_writer <- pin_file_writer(
~arrow::write_feather(.x, .y, compression = "uncompressed"),
extension = "arrow"
)
board <- board_temp()
pin_write(board, mtcars, type = arrow_pin_writer)
#> Using `name = 'mtcars'`
#> Creating new version '20220914T202009Z-8a125'
#> Writing to pin 'mtcars'
pin_upload(board, arrow_pin_writer(mtcars))
#> Guessing `name = 'mtcars.arrow'`
#> Creating new version '20220914T202009Z-8a125'
pin_download(board, "mtcars") |> arrow::read_feather() |> head()
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#> 2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#> 3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#> 4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#> 5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
#> 6 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
pin_download(board, "mtcars.arrow") |> arrow::read_feather() |> head()
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#> 2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#> 3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#> 4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#> 5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
#> 6 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 Created on 2022-09-14 by the reprex package (v2.0.1) One thing that does not appear in the reprex, but does appear interactively: pin_upload(board, arrow_pin_writer(mtcars))
I think this is happening because Assuming things are OK, some questions:
Thanks! |
So.... I am not feeling great about the HOWEVER, I am really excited about making this work better via This fills the need, if I am understanding correctly? library(pins)
b <- board_temp()
pin_name <- "my-mtcars"
path <- fs::path_temp(fs::path_ext_set(pin_name, "arrow"))
arrow::write_feather(mtcars, path, compression = "uncompressed")
b %>% pin_upload(path, pin_name, title = "My very excellent cars")
#> Creating new version '20220921T174004Z-8a125' Created on 2022-09-21 with reprex v2.0.2 What do you think we could do to make this a nicer user experience? |
I think the |
That would be perfect @ijlyttle! Thank you for being willing to work through this in the way we did. |
This pull request has been automatically locked. If you believe you have found a related problem, please file a new issue (with a reprex: https://reprex.tidyverse.org) and link to this issue. |
fix #631
Sorry for delay, I finally got enough things pushed to the side of my "plate" so that I can devote some time to this - this draft is just to indicate I have not forgotten this or #627 .