-
Notifications
You must be signed in to change notification settings - Fork 197
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
Transform int to 0/1 before coercion to logical #398
Conversation
Fixes #385 Weirdly, the test passes even without this fix when run with `testthat::test()`. To get the test to fail, checkout the previous commit, install, and do ```r library(readxl) library(testthat) source("./tests/testthat/helper.R") source("./tests/testthat/test-col-types.R") ``` from within the project directory. It will segfault.
Nice! Yes I had figured something like this was going on, but it's a big help to have it tracked down and fixed. Thanks! I can reproduce almost everything you say, except this:
I am running dev testthat and it does indeed catch it and correctly reports |
@jimhester I'm going to merge this. It's super small but important and a good lesson. Will you speak up if this is somehow not the correct fix? The linked issue will illustrate the problem this fixes. |
@nacnudus Will you make another PR with a bullet in NEWS? |
@@ -256,7 +256,7 @@ class XlsxCell { | |||
case CELL_NUMERIC: | |||
{ | |||
rapidxml::xml_node<>* v = cell_->first_node("v"); | |||
return atoi(v->value()); | |||
return atoi(v->value()) != 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not seem correct, won't this convert any numeric value to 0 or 1? You only want to do this for the CELL_LOGICAL
case, not both, no?
Also I think it is maybe clearer to be more explicit and use
return atoi(v->value()) != 0 ? 1 : 0;
But that is subjective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is correct, in terms of how asInteger
is actually used. It is only called when putting numeric data into logical cells.
But, yes, it suggests asInteger
should perhaps be renamed to asLogical
. Or I should have both. Or there should at least be a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be asLogical
and I would use Rf_LogicalFromReal()
to do the conversion, which also handles the NaN case.
return Rf_LogicalFromReal(atoi(v->value()), nullptr);
Fixes #385
The clue to solving this issue was in this twitter thread. Integers are coerced to logical in two places. One place does
where
Rf_ScalarLogical
transforms non-zero integers to 1 before coercing to logical. But the other place doesLOGICAL(column)[row] = xcell->asInteger();
Weirdly, the test passes even without this fix when run with
testthat::test()
. To get the test to fail (in fact, segfault), checkout the previous commit, install, and from within the project directory do