Skip to content
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

246 flexible delayed choices #247

Merged

Conversation

chlebowa
Copy link
Contributor

@chlebowa chlebowa commented Feb 3, 2025

Closes #246

Added functions first_choices and last_choices to allow for specifying subset as "first n" and "last n" of available choices.
Both functions take argument n which must be integer-line and greated than 1. This way specifying first_choices(2) automatically sets multiple = TRUE where appropriate.
Class all_choices is changed to class multiple_choices.

@gogonzo
Copy link
Contributor

gogonzo commented Feb 4, 2025

@donyunardi please wait with the release until this is merged 👍

@gogonzo gogonzo added the core label Feb 4, 2025
@gogonzo gogonzo self-assigned this Feb 4, 2025
Copy link
Contributor

@gogonzo gogonzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first_choice should be now:

first_choice <- function() {
  out <- first_choices(1)
  class(out) <- c("delayed_choices", "delayed_data")
  out
}

R/delayed_choices.R Outdated Show resolved Hide resolved
R/delayed_choices.R Outdated Show resolved Hide resolved
R/delayed_choices.R Outdated Show resolved Hide resolved
R/delayed_choices.R Outdated Show resolved Hide resolved
@chlebowa
Copy link
Contributor Author

chlebowa commented Feb 4, 2025

first_choice should be now:

first_choice <- function() {
  out <- first_choices(1)
  class(out) <- c("delayed_choices", "delayed_data")
  out
}

No. There must be a distinction because the multiple argument defaults to FALSE for first_choice() and to TRUE for first_choices(n), so the class multiple_choices is necessary.

Allowing n = 1 in first_choices is a valid point, though, because one might want to allow multiple but select only one. Do you want to me to loosen the assertion?

@chlebowa chlebowa requested a review from gogonzo February 4, 2025 12:37
@chlebowa
Copy link
Contributor Author

chlebowa commented Feb 4, 2025

first_choice should be now:

first_choice <- function() {
  out <- first_choices(1)
  class(out) <- c("delayed_choices", "delayed_data")
  out
}

No. There must be a distinction because the multiple argument defaults to FALSE for first_choice() and to TRUE for first_choices(n), so the class multiple_choices is necessary.

Allowing n = 1 in first_choices is a valid point, though, because one might want to allow multiple but select only one. Do you want to me to loosen the assertion?

Sorry, I misread your comment.

I think it's better to have independent implementations but if you prefer this way, I'll change it.

@gogonzo
Copy link
Contributor

gogonzo commented Feb 4, 2025

first_choice should be now:

first_choice <- function() {
  out <- first_choices(1)
  class(out) <- c("delayed_choices", "delayed_data")
  out
}

No. There must be a distinction because the multiple argument defaults to FALSE for first_choice() and to TRUE for first_choices(n), so the class multiple_choices is necessary.
Allowing n = 1 in first_choices is a valid point, though, because one might want to allow multiple but select only one. Do you want to me to loosen the assertion?

Sorry, I misread your comment.

I think it's better to have independent implementations but if you prefer this way, I'll change it.

I think there is even more room for improvement. All these functions repeat the same condition. Please create a private function which can evaluate custom functions:

  • first_choice: function(x) head(x, 1)
  • last_choice: function(x) tail(x, 1)
  • first_choices: function(x) head(x, n)
  • last_choices: function(x) tail(x, n)
.delayed_choices <- function(fun) {
   structure(
    function(x) {
      if (inherits(x, "delayed_choices")) {
        x
      } else if (length(x) == 0L) {
        x
      } else if (is.atomic(x)) {
        fun(x)
      } else if (inherits(x, "delayed_data")) {
        if (is.null(x$subset)) return(x)
        original_fun <- x$subset
        x$subset <- function(data) {
          fun_x(original_fun(data))
        }
        x
      }
    },
    class = c("delayed_choices", "delayed_data")
  )
}

first_choices <- function(n) {
  out <- .delayed_choices(fun = function(x) tail(x, n))
  class(out) <- c("multiple_choices", class(out))
  out
}

@chlebowa
Copy link
Contributor Author

chlebowa commented Feb 4, 2025

Something like that was an idea I had but I didn't want to overcomplicate things prematurely 😉

Copy link
Contributor

@gogonzo gogonzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! 👍

@gogonzo gogonzo merged commit 50f6529 into insightsengineering:main Feb 4, 2025
28 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Feb 4, 2025
@chlebowa chlebowa deleted the 246_flexible_delayed_choices@main branch February 4, 2025 15:16
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

More flexibility in delayed_choices
2 participants