Skip to content

Conversation

@jangorecki
Copy link
Member

@jangorecki jangorecki commented Aug 3, 2019

closes #3740
important changes to discuss (fyi @2005m):

  • feature removed of en-listing singleton replacement into list (when another option was of type list).
    I am not against this feature, but it seems to be not straightforward to address issue related to it in a consistent way. I prefer hutils/dplyr behaviour to raise error when yes is a list and no is an atomic. As a result, user will need to wrap no into extra list to match data types.
DT = data.table(a = 0:5, b = list(1, list(2:3), list(4:6), list(6:4), list(3:2), 1))

DT[ , b1 := fifelse(a > 2, b, 0)][]
# become
DT[ , b2 := fifelse(a > 2, b, list(0))][]

This shouldn't be big deal. I think it make sense when we want to use it on a list column.

  • names are retained from test argument, so names of lists provided to yes/no are not retained anymore.
    I don't see a reason why we would retain names of a list in yes/no but not for named atomic vectors. Make sense to stick to base way, so retaining names of test. If we want to really handle also names from yes and no then make sense to do it for any named input, not just list.
names(fifelse(c(a=T,b=F), list(m=1,n=2), list(x=11,y=12)))
names(ifelse(c(a=T,b=F), list(m=1,n=2), list(x=11,y=12)))
names(fifelse(c(a=T,b=F), c(m=1,n=2), c(x=11,y=12)))
names(ifelse(c(a=T,b=F), c(m=1,n=2), c(x=11,y=12)))
names(fifelse(c(a=T,b=F), c(1,2), c(11,12)))
names(ifelse(c(a=T,b=F), c(1,2), c(11,12)))

@jangorecki jangorecki added the WIP label Aug 3, 2019
@codecov
Copy link

codecov bot commented Aug 3, 2019

Codecov Report

Merging #3741 into master will decrease coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3741      +/-   ##
==========================================
- Coverage   99.41%   99.41%   -0.01%     
==========================================
  Files          71       71              
  Lines       13208    13196      -12     
==========================================
- Hits        13131    13119      -12     
  Misses         77       77
Impacted Files Coverage Δ
R/wrappers.R 100% <100%> (ø) ⬆️
src/fifelse.c 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d959107...a3b15aa. Read the comment docs.

test(2072.047, fifelse(FALSE, data.table(1:5), data.table(5:1)), data.table(5:1))
test(2072.048, fifelse(TRUE, data.frame(1:5), data.frame(5:1)), data.frame(1:5))
test(2072.049, fifelse(FALSE, data.frame(1:5), data.frame(5:1)), data.frame(5:1))
test(2072.046, fifelse(TRUE, list(data.table(1:5)), list(data.table(5:1))), list(data.table(1:5)))
Copy link
Member Author

@jangorecki jangorecki Aug 3, 2019

Choose a reason for hiding this comment

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

I think it is improper use. data.frame should be handled as ordinary list here, thus wrapping into list to achieve equality. Consider

fifelse(TRUE, data.table(1:5, 2:6), data.table(5:1, 6:2))

@jangorecki jangorecki removed the WIP label Aug 3, 2019
@jangorecki jangorecki requested a review from mattdowle August 3, 2019 13:17
if (len1!=1 && len1!=len0) error("Length of 'yes' is %lld but must be 1 or length of 'test' (%lld).", len1, len0);
if (len2!=1 && len2!=len0) error("Length of 'no' is %lld but must be 1 or length of 'test' (%lld).", len2, len0);
const int64_t amask = len1>1 ? INT64_MAX : 0;
const int64_t amask = len1>1 ? INT64_MAX : 0; // for scalar 'a' bitwise AND will reset iterator to first element: pa[i & amask] -> pa[0]
Copy link
Member

Choose a reason for hiding this comment

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

oh i see now. helpful comment indeed!

and the thinking is the compiler will optimize away all the repeated & calls?

Copy link
Member Author

@jangorecki jangorecki Aug 3, 2019

Choose a reason for hiding this comment

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

bitwise AND of any_number & 0 will result 0, while of any_number & max_number will result any_number, due to the fact that max_number is represented by all 1 numbers, i.e. for 4 bit unsigned integer: 1 & 15 -> 0001 & 1111 results 0001.
I have no idea how compiler approach that

Copy link
Member

@mattdowle mattdowle Aug 26, 2019

Choose a reason for hiding this comment

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

It's just that the & is so fast that it doesn't matter. It is so fast that it can probably be done within the CPU's pipeline 'for free' without affecting measurable timings outside the pipeline.
The compiler can't optimize it away because it doesn't know what will be in mask. The mask is declared as const so that the compiler can registerize its use though; i.e. it doesn't need to keep checking whether amask has changed within the loop.

@2005m
Copy link
Contributor

2005m commented Aug 3, 2019

Thank you Jan, I will have a look at the changes. What about coercing logical, complex and string (like ifelse) instead of just int to double? I can look at it and suggest something if you want?
I can try to suggest something for en-listing as well.

@jangorecki
Copy link
Member Author

jangorecki commented Aug 3, 2019

@2005m I prefer to have strict type checks and require user to provide correct ones. But... I think int-double is good exception here, because it is so widely used, and still make sense, while coercing numeric to character is rather useless.
If you can address en-listing issue then sure, but returning different type depending on test arguments is pretty bad behaviour of base ifelse

ifelse(c(T,F), 1L, list(0))
ifelse(c(T,T), 1L, list(0))

@mattdowle mattdowle added this to the 1.12.4 milestone Aug 26, 2019
@mattdowle mattdowle merged commit f4fb3d6 into master Aug 26, 2019
@mattdowle mattdowle deleted the fifelse2 branch August 26, 2019 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fifelse followup

4 participants