2

In my Data, I'm trying to change y to qlogis(y) when dv=="B".

But I wonder why I get a warning message saying NaNs produced?

Note that .5 and .6 are between 0 and 1 and shouldn't return any NaNs.

library(dplyr)

Data = read.table(text=
"
id dv y
1  A  2
1  B  .5
1  C  11
2  A  4
2  B  .6
2  C  19
", h=TRUE)

mutate(Data, y = ifelse(dv=="B", qlogis(y), y))
Simon Harmel
  • 927
  • 2
  • 9

1 Answers1

1

We may use replace to apply only qlogis to subset of data and not on the full data

library(dplyr)
Data %>% 
   mutate(y = replace(y, dv == "B", qlogis(y[dv == "B"])))

-output

 id dv          y
1  1  A  2.0000000
2  1  B  0.0000000
3  1  C 11.0000000
4  2  A  4.0000000
5  2  B  0.4054651
6  2  C 19.0000000

i.e.

> qlogis(2)
[1] NaN
Warning message:
In qlogis(2) : NaNs produced
> qlogis(0.5)
[1] 0

The warning is related to how the ifelse process the output i..e all the arguments should have the same length. Thus, qlogis(y) gets applied to the whole column and inside the function, it is processed so that only a subset is returned. But, the warning already comes from the qlogis function resulting from NaN on values greater than 1. i.e. in the source code

...
p = log(lower_tail ? (p / (1. - p)) : ((1. - p) / p));
...

Thus a value greater than 1 with default case of lower.tail argument TRUE

> log((2/(1-2)))
[1] NaN
> log((1/(1-1)))
[1] Inf
> qlogis(1)
[1] Inf
> qlogis(0.9)
[1] 2.197225
> qlogis(1.2)
[1] NaN
Warning message:
In qlogis(1.2) : NaNs produced
ifelse
function (test, yes, no) 
{
...

 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]
    ans
...

Now, we do the same steps as in the ifelse code

> test <- Data$dv == "B"
> ans <- test
>  len <- length(ans)
>     ypos <- which(test)
>     npos <- which(!test)
> ypos
[1] 2 5
> npos
[1] 1 3 4 6
> yes <- qlogis(Data$y)### it is the input on the whole column
Warning message:
In qlogis(Data$y) : NaNs produced
akrun
  • 874,273
  • 37
  • 540
  • 662
  • I get the same result as akrun with `Data %>% mutate(y = if_else(dv=="B", qlogis(y), y))` – TarJae Dec 29 '22 at 20:10
  • 1
    @TarJae There is a warning with `ifelse/if_else/case_when` as it is related to the source code – akrun Dec 29 '22 at 20:11
  • @SimonHarmel the warning comes from `qlogis` when the input value is greater than 1. Please see the update in the post – akrun Dec 29 '22 at 20:20
  • @SimonHarmel i.e the reason I used `replace` to subset and apply only the elements that satistify dv == 'B'. `ifelse` applies on the whole column, and later subset the output, whereas `replace` applies on the subset and returns the subset output that satisfy the condition – akrun Dec 29 '22 at 20:28
  • A [question of interest](https://stackoverflow.com/q/74998962/16762740). – Simon Harmel Jan 03 '23 at 22:33
  • @SimonHarmel Please check the solution posted – akrun Jan 04 '23 at 06:30