Are arithmetic operators ever preferable to arithmetic functions?

前端 未结 1 1655
轮回少年
轮回少年 2021-01-19 20:40

I\'ve noticed there are some instances in which an arithmetic operator (in backticks) acts as if it is an arithmetic function.

Arithmetic operator:

&         


        
1条回答
  •  走了就别回头了
    2021-01-19 21:12

    To the question in the title, I would say ..often or typically. In R we are often working on columns or vectors in parallel, i,e, the order of the values in a vector matter in the sense of being part of the same case or subject. In your examples you are actually seeing three different functions in action:

    First: the unary '+' operator which basically does nothing when given numeric vectors but would do coercion to numeric when given logical vectors:

    >  `+`(-3:3)
    [1] -3 -2 -1  0  1  2  3
    > `+`(c(TRUE,FALSE))
    [1] 1 0
    

    Notice that it does not make all of its returned values positive as was stated in one of the comments.

    Next: the binary '+` operator:

    > `+`(-3:3, 0:6)
    [1] -3 -1  1  3  5  7  9
    

    And finally: the sum function, which is _not_vectorized_ and will collapse all values to the sum of their union:

    > sum(-3:3, 0:6, c(TRUE,FALSE) )
    [1] 22
    

    The binary + will also recycle arguments (with a warning):

    > `+`(-3:3, c(TRUE,FALSE) )
    [1] -2 -2  0  0  2  2  4
    Warning message:
    In -3:3 + c(TRUE, FALSE) :
      longer object length is not a multiple of shorter object length
    

    When operating on vectors "in parallel" you will often want to use the vectorized operators and be very much disappointed by the results of sum which can only return a value of length 1. Some functions like outer which depend on a functional argument require that the function be vectorized.

    >  outer(1:4, 5:8, sum)
    Error in outer(1:4, 5:8, sum) : 
      dims [product 16] do not match the length of object [1]
    > outer(1:4, 5:8, "+")
         [,1] [,2] [,3] [,4]
    [1,]    6    7    8    9
    [2,]    7    8    9   10
    [3,]    8    9   10   11
    [4,]    9   10   11   12
    

    Others require that a single value be returned. And some others like 'mapply` are agnostic on the subject.

    > mapply(sum, 1:4, 5:8)
    [1]  6  8 10 12
    > mapply("+", 1:4, 5:8)
    [1]  6  8 10 12
    

    The Vectorize can be used to create a version of a non-vectorized function and internally it is using mapply to return a different function, but it is limited to non-primitive functions since they do not use argument names in their formals list (so you cannot vectorize sum.)

    It should probably be noted in closing that these have different precedence for which one can get R precedence rules by consulting ?Syntax. (The unary arithmetic operators have higher precedence than the binary ones. Functions and parentheses implicitly would have the highest precedence. I have seen situations where there were surprises due to the higher precedence of user defined functions.)

    0 讨论(0)
提交回复
热议问题