-
Notifications
You must be signed in to change notification settings - Fork 128
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
pretty printing of plans #489
Comments
This would be a very, very nice feature. |
How about a pretty-print method that prints/returns a |
Brilliant! Much easier and just as good. |
We will just have to make it really clear that the plan is just a data frame and that people do not always need to use > print(plan)
data frame generated by drake_plan(
u_auckland = make_place(
Name = "University of Auckland",
Latitude = -36.8521369,
Longitude = 174.7688785
)
shapefile = {
file_out(
"u-auckland.prj",
"u-auckland.shx",
"u-auckland.dbf"
)
st_write(
obj = u_auckland,
dsn = file_out("u-auckland.shp"),
driver = "ESRI Shapefile",
delete_dsn = TRUE
)
}
) |
We should define a special S3 class and print method for printing, and I am having some initial trouble. The guide on extending as_drake_plan <- function(x, ...){
class(x) <- c("drake_plan", "tbl_df", "tbl", "data.frame")
x
}
drake_plan.as.data.frame <- as_drake_plan
drake_plan.as_data_frame <- as_drake_plan
drake_plan.as_tibble <- as_drake_plan
drake_plan.as.tibble <- as_drake_plan
`[.drake_plan` <- function(...){
as_drake_plan(NextMethod())
}
library(dplyr)
library(drake)
plan <- drake_plan(
x = get_data(),
y = analyze_data(x)
) %>%
as_drake_plan() %>%
print
#> # A tibble: 2 x 2
#> target command
#> * <chr> <chr>
#> 1 x get_data()
#> 2 y analyze_data(x)
class(plan)
#> [1] "drake_plan" "tbl_df" "tbl" "data.frame"
filter(plan, target == "x") %>%
class()
#> [1] "tbl_df" "tbl" "data.frame" Related Stack Overflow post here. |
Just started to construct the call in the |
We now have an internal |
Next steps:
|
Update: from #494, we now have a special |
Continued work on this will be in the files |
So apparently, dropping |
@lorenzwalthert, I would like to include you in this conversation too. This feature is likely to require a custom |
Thanks. I think the fact that attributes and sub classes are generally not preserved in R are a pitty and limit the usefulness of this mission slightly. Anyways, |
Yeah, not the best circumstances, but I still think this feature is worth exploring. I laid the groundwork for drake::load_mtcars_example()
my_plan$trigger <- NA
my_plan$trigger[4] <- "trigger(condition = is_tuesday(), file = FALSE)"
my_plan$non_standard_column <- 1234
# Long commands are often truncated this way:
print(my_plan)
#> # A tibble: 15 x 4
#> target command trigger non_standard_co…
#> <chr> <chr> <chr> <dbl>
#> 1 report "knit(knitr_in(\"report… <NA> 1234
#> 2 small simulate(48) <NA> 1234
#> 3 large simulate(64) <NA> 1234
#> 4 regression… reg1(small) trigger(conditio… 1234
#> 5 regression… reg1(large) <NA> 1234
#> 6 regression… reg2(small) <NA> 1234
#> 7 regression… reg2(large) <NA> 1234
#> 8 summ_regre… suppressWarnings(summar… <NA> 1234
#> 9 summ_regre… suppressWarnings(summar… <NA> 1234
#> 10 summ_regre… suppressWarnings(summar… <NA> 1234
#> 11 summ_regre… suppressWarnings(summar… <NA> 1234
#> 12 coef_regre… suppressWarnings(summar… <NA> 1234
#> 13 coef_regre… suppressWarnings(summar… <NA> 1234
#> 14 coef_regre… suppressWarnings(summar… <NA> 1234
#> 15 coef_regre… suppressWarnings(summar… <NA> 1234
# So we might style a drake_plan() call that could generate the plan.
call <- drake:::drake_plan_call(my_plan)
str(call)
#> language drake_plan(report = knit(knitr_in("report.Rmd"), file_out("report.md"), quiet = TRUE), small = simulate(48),| __truncated__ ...
# But the default print method does not guide intuition.
print(call)
#> drake_plan(report = knit(knitr_in("report.Rmd"), file_out("report.md"),
#> quiet = TRUE), small = simulate(48), large = simulate(64),
#> regression1_small = target(command = reg1(small), trigger = trigger(condition = is_tuesday(),
#> file = FALSE)), regression1_large = reg1(large), regression2_small = reg2(small),
#> regression2_large = reg2(large), summ_regression1_small = suppressWarnings(summary(regression1_small$residuals)),
#> summ_regression1_large = suppressWarnings(summary(regression1_large$residuals)),
#> summ_regression2_small = suppressWarnings(summary(regression2_small$residuals)),
#> summ_regression2_large = suppressWarnings(summary(regression2_large$residuals)),
#> coef_regression1_small = suppressWarnings(summary(regression1_small))$coefficients,
#> coef_regression1_large = suppressWarnings(summary(regression1_large))$coefficients,
#> coef_regression2_small = suppressWarnings(summary(regression2_small))$coefficients,
#> coef_regression2_large = suppressWarnings(summary(regression2_large))$coefficients) My main preference is to arrange this output in a 2-column grid with each target on its own set of rows. Thank you for offering to provide guidance. It will really help to draw on your aesthetic opinions and |
After letting this issue sit for a few days, I no longer think the Most of the remaining work for that is to create a custom style guide. Relevant: https://lorenzwalthert.netlify.com/posts/customizing-styler-the-quick-way/ |
I think the syntax highlighting piece may be better suited to |
To be honest, I think you don't even need |
Sure, seems to work fine in my own console. |
Ok, cool. I mean you can still use styler to prettify your code beforehand according to a (custom) style guide. |
Absolutely. I am in the beginnings of constructing a custom style guide to manage line breaks and indentation. The desired output is a pkgconfig::set_config("drake::strings_in_dots" = "literals")
plan <- drake::drake_plan(
small_data = download_data("https://some_website.com") %>%
select_my_columns() %>%
munge(),
large_data_raw = target(
command = download_data("https://lots_of_data.com") %>%
select_top_columns,
trigger = trigger(
change = time_last_modified("https://lots_of_data.com"),
command = FALSE,
depend = FALSE
),
timeout = 1e3
)
) Text to begin with: call <- drake:::drake_plan_call(plan)
text <- rlang::expr_text(call, width = 70)
text
#> [1] "drake_plan(small_data = download_data(\"https://some_website.com\") %>% select_my_columns() %>% \n munge(), large_data_raw = target(command = download_data(\"https://lots_of_data.com\") %>% \n select_top_columns, trigger = trigger(change = time_last_modified(\"https://lots_of_data.com\"), \n command = FALSE, depend = FALSE), timeout = 1000))" |
I'm a little unclear about the role of add_line_breaks <- function(pd_flat){
pd_flat$newlines <- pd_flat$newlines + (pd_flat$token == "SYMBOL_SUB")
pd_flat
}
guide <- function(){
styler::create_style_guide(line_break = tibble::lst(add_line_breaks))
}
styled <- styler::style_text(text, style = guide)
cat(prettycode::highlight(styled), sep = "\n")
#> drake_plan(small_data = download_data("https://some_website.com") %>% select_my_columns() %>%
#> munge(), large_data_raw = target(command = download_data("https://lots_of_data.com") %>%
#> select_top_columns, trigger = trigger(change = time_last_modified("https://lots_of_data.com"),
#> command = FALSE, depend = FALSE), timeout = 1000)) And with add_line_breaks <- function(pd_flat){
pd_flat$lag_newlines <- pd_flat$lag_newlines | (pd_flat$token == "SYMBOL_SUB")
pd_flat
}
guide <- function(){
styler::create_style_guide(line_break = tibble::lst(add_line_breaks))
}
styled <- styler::style_text(text, style = guide)
cat(prettycode::highlight(styled), sep = "\n")
#> drake_plan(
#> small_data = download_data("https://some_website.com") %>% select_my_columns() %>%
#> munge(),
#> large_data_raw = target(
#> command = download_data("https://lots_of_data.com") %>%
#> select_top_columns,
#> trigger = trigger(
#> change = time_last_modified("https://lots_of_data.com"),
#> command = FALSE,
#> depend = FALSE),
#> timeout = 1000)) |
I think it is appropriate to have:
Any suggestions on wrangling |
I figured out a solution: at the top level, recurse the AST of a library(drake)
plan <- drake_plan(
small_data = download_data("https://some_website.com") %>%
select_my_columns() %>%
munge(),
large_data_raw = target(
command = download_data("https://lots_of_data.com") %>%
select_top_columns,
trigger = trigger(
change = time_last_modified("https://lots_of_data.com"),
command = FALSE,
depend = FALSE
),
timeout = 1e3
),
strings_in_dots = "literals"
)
print(plan)
#> # A tibble: 2 x 4
#> target command trigger timeout
#> * <chr> <chr> <chr> <dbl>
#> 1 small_da… "download_data(\"https://s… <NA> NA
#> 2 large_da… "download_data(\"https://l… "trigger(change = time_la… 1000
drake_plan_source(plan)
#> drake_plan(
#> small_data = download_data("https://some_website.com") %>%
#> select_my_columns() %>%
#> munge(),
#> large_data_raw =target(
#> command = download_data("https://lots_of_data.com") %>% select_top_columns(),
#> trigger =trigger(
#> change = time_last_modified("https://lots_of_data.com"),
#> command = FALSE,
#> depend = FALSE
#> ),
#> timeout = 1000
#> ),
#> strings_in_dots = "literals"
#> ) |
I do like the simplicity of deferring to |
This indeed seems complicated. What are the requirements for the styling? E.g. line break after |
That's part of it. I would prefer each of the following to start on its own line:
This, plus the indentation above, are what I am after. I take it this is difficult to do in |
FYI: The |
Good point. I forgot I already defined a |
The problem with a style guide is that all rules are not exported from styler, so you needed |
Update: the current behavior is to create a special library(drake)
drake_plan(
data = get_data(),
y = analyze_data(data)
)
#> # A tibble: 2 x 2
#> target command
#> <chr> <expr>
#> 1 data get_data()
#> 2 y analyze_data(data) Created on 2019-05-06 by the reprex package (v0.2.1) Drawbacks:
So I would rather rely on r-lib/pillar#34 and r-lib/pillar#153. But because |
It is difficult to visually inspect long commands in workflow plan data frames. Example: #257 (comment).
Desired output:
I am not sure if this is possible, but I think it may be worth trying some combination of
pillar::pillar_shaft()
,styler
,highlight
, andcrayon
.The text was updated successfully, but these errors were encountered: