-
Notifications
You must be signed in to change notification settings - Fork 967
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
fifelse did not work in recursive function #4549
Comments
Thanks for the MRE! Not sure why it's recursing so much in the first place...
|
Base ans <- test
len <- length(ans)
ypos <- which(test)
npos <- which(!test)
if (length(ypos) > 0L)
ans[ypos] <- rep(yes, length.out = len)[ypos]
if (length(npos) > 0L)
ans[npos] <- rep(no, length.out = len)[npos] For We could address it by incorporating some of fifelse2 = function(test, yes, no, na) {
if (is.atomic(test)) {
if (typeof(test) != "logical")
storage.mode(test) = "logical"
if (length(test) == 1L) {
if (is.na(test)) {
if (missing(na))
return (NA)
else
return(na)
}
if (test)
return(yes)
else
return(no)
} else {
.Call(data.table:::CfifelseR, test, yes, no, na)
}
} else {
stop("Argument 'test' must be logical")
}
}
n_dt2 = 0
gcd_dt2 <- function(x,y) {
cat('Recursion level:', n_dt <<- n_dt + 1, '\n')
r <- x%%y
return(fifelse2(r, gcd_dt(y, r), y))
}
gcd_dt2(10, 1)
##Recursion level: 1
##[1] 1 Note, if this were implemented, this would not check the type of |
Alternatively we would have to substitute input, pass together with parent.frame to C, unevaluated, which complicates a lot. I don't like to use lazy evaluation when it is not really necessary. |
tidyverse/dplyr#5341 Both issues were closed due to concerns for type stability (e.g., both Regardless, I believe we have some |
I think what should be done in this issue is to document (if not already documented) that fifelse, contrary to base ifelse, evaluates both arguments. Then mention fcase which provides similar functionality (+ ensure examples included). Then add unit test (and ideally examples) for fcase to confirm such usage works fine. NB. I was just looking for fast vectorized GCD and there doesn't seem anything nice out there. @hongyuanjia you may want to fill FR for that particularly, you will get my upvote, but not guaranteed it to get to in-scope of DT. |
@jangorecki, I confirmed that this behavior has not yet been documented. Also, for a fast vectorized GCD, {collapse} has one, i.e. |
I am trying to use
data.table::fifelse
to implement a recursive function to calculate greatest common divisors mentioned in this StackOverflow. However, I found that in this case,data.table::fifelse
cannot be a replacement forbase::ifelse
.Minimal reproducible
Any insights? Thanks!
The text was updated successfully, but these errors were encountered: