[Rd] plogis (and other p* functions), vectorized lower.tail

Sokol Serguei @oko| @end|ng |rom |n@@-tou|ou@e@|r
Thu Dec 9 17:13:36 CET 2021


On 09/12/2021 16:55, Ben Bolker wrote:
>
>
> On 12/9/21 10:03 AM, Martin Maechler wrote:
>>>>>>> Matthias Gondan
>>>>>>>      on Wed, 8 Dec 2021 19:37:09 +0100 writes:
>>
>>      > Dear R developers,
>>      > I have seen that plogis silently ignores vector elements of 
>> lower.tail,
>>
>> and also of 'log'.
>> This is indeed the case for all d*, p*, q* functions.
>>
>> Yes, this has been on purpose and therefore documented, in the
>> case of plogis, e.g. in the 'Value' section of ?plogis :
>>
>>       The length of the result is determined by ‘n’ for ‘rlogis’, and is
>>       the maximum of the lengths of the numerical arguments for the
>>       other functions.
>>
>>   (note: *numerical* arguments: the logical ones are not recycled)
>>
>>       The numerical arguments other than ‘n’ are recycled to the length
>>       of the result.  Only the first elements of the logical arguments
>>       are used.
>>
>>   (above, we even explicitly mention the logical arguments ..)
>>
>>
>> Recycling happens for the first argument (x,p,q) of these
>> functions and for "parameters" of the distribution, but not for
>> lower.tail, log.p (or 'log').
>>
>>
>>      >> plogis(q=0.5, location=1, lower.tail=TRUE)
>>      > [1] 0.3775407
>>      >> plogis(q=0.5, location=1, lower.tail=FALSE)
>>      > [1] 0.6224593
>>      >> plogis(q=c(0.5, 0.5), location=1, lower.tail=c(TRUE, FALSE))
>>      > [1] 0.3775407 0.3775407
>>
>>      > For those familiar with psychological measurement: A use case 
>> of the above function is the so-called Rasch model, where the 
>> probability that a person with some specific ability (q) makes a 
>> correct (lower.tail=TRUE) or wrong response (lower.tail=FALSE) to an 
>> item with a specific difficulty (location). A vectorized version of 
>> plogis would enable to determine the likelihood of an entire response 
>> vector in a single call. My current workaround is an intermediate 
>> call to „Vectorize“.
>>
>>      > I am wondering if the logical argument of lower.tail can be 
>> vectorized (?). I see that this may be a substantial change in many 
>> places (basically, all p and q functions of probability 
>> distributions), but in my understanding, it would not break existing 
>> code which assumes lower.tail to be a single element. If that’s not
>>      > possible/feasible, I suggest to issue a warning if a vector of 
>> length > 1 is given in lower.tail. I am aware that the documentation 
>> clearly states that lower.tail is a single boolean.
>>
>> aah ok, here you say you know that the current behavior is documented.
>>
>>      > Thank you for your consideration.
>>
>>
>> As you mention, changing this would be quite a large endeavor.
>> I had thought about doing that many years ago, not remembering
>> details, but seeing that in almost all situations you really
>> only need one of the two tails  (for Gaussian- or t- based confidence
>> intervals you also only need one, for symmetry reason).
>>
>> Allowing the recycling there would make the intermediate C code
>> (which does the recycling) larger and probably slightly
>> slower because of conceptually two more for loops which would in
>> 99.9% only have one case ..
>>
>> I'd have found that ugly to add. ... ...
>> ... but of course, if you can prove that the code bloat would not be 
>> large
>> and not deteriorate speed in a measurable way and if you'd find
>> someone to produce a comprehensive and tested patch ...
>>
>> Martin
>>
>>
>>      > With best wishes,
>>      > Matthias
>>
>>
>>
>>      > [[alternative HTML version deleted]]
>>
>>      > ______________________________________________
>>      > R-devel using r-project.org mailing list
>>      > https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>> ______________________________________________
>> R-devel using r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
>   I agree with everything said above, but think that adding a warning 
> when length(lower.tail) > 1 (rather than silently ignoring) might be 
> helpful ...  ??
>
>   As for the vectorization, it seems almost trivial to do at the user 
> level when needed (albeit it's probably a little bit inefficient):
>
> pv <- Vectorize(plogis, c("q", "location", "scale", "lower.tail"))
> pv(q=c(0.5, 0.5), location=1, lower.tail=c(TRUE, FALSE))
> [1] 0.3775407 0.6224593

.. or directly use mapply()

mapply(plogis, q=c(0.5, 0.5), location=1, lower.tail=c(TRUE, FALSE))
[1] 0.3775407 0.6224593



More information about the R-devel mailing list