How to supress arithmetric operators in a formula in R - r

I'm attempting to define an infix function %~% that takes a character on the left and an expression on the right and returns a concatenated formula object. So what I want "y" %~% x + z to return y ~ x + z.
However, my function (below) fails to use the + as a symbolic formula operator, and instead defaults to an arithmetic operator. Clearly, the ~ infix function acheives this, but it's a primitive function, so I (think I) can't go swipe the code, and I don't know how to incorporate it into the function definition to acheive my desired results.
`%~%` <- function(x, y) {
y <- deparse(substitute(y))
formula(paste(x, "~", y)
}
A solution is to use the ~ operator when calling the function:
"y" %~%~ x + z
but I'm wondering if there is a way to prevent the evaluation of + as an arithmetic operator in the function definition so that I can simply use %~%.

The order or operator precedence is fixed in R, and a little experimentation (or checking of the ?Syntax help page) shows that the special operators bind tighter than the + and - operators:
`%~%` = function(left,right){
cat("left: ",as.character(substitute(left)), " right: ", as.character(substitute(right)),'\n')
return(100)
}
which yields:
> 2 %~% 1 + 3
left: 2 right: 1
[1] 103
> 2 %~% (1 + 3)
left: 2 right: ( 1 + 3
[1] 100
or maybe a bit more clearly:
zz <- function(x){
x <- substitute(x)
cat(sprintf("%s [%s] %s\n",
as.character(deparse(x[[2]])),
as.character(deparse(x[[1]])),
as.character(deparse(x[[3]]))))}
which yields:
> zz(1 + 2)
1 [+] 2
> zz(1 + 2:3)
1 [+] 2:3
> zz(1 + 2%foo%3)
1 [+] 2 %foo% 3
> zz(2%foo%3+1)
2 %foo% 3 [+] 1
Note also that formula's capture the environment in which they are created, so creating a formula in a helper function may have some unexpected and difficult to debug consequences if you don't take care to bind the correct environment to your formula object.

Related

Using mosaicCalc::D() to differentiate expression giving unexpected result

I am attempting to differentiate the expression -1+3*x^2/1+x^2 with respect to x, but the output is incorrect. The correct output should be:
8x/(1+x^2)^2
#> library(mosaicCalc)
#>
#> l=D(-1+3*x^2/1+x^2 ~x)
#> l
function (x)
8 * x
Edit:
I have used parenthesis, but the output is still incorrect
#> t=D((-1+3*x^2)/1+x^2 ~x)
#> t
function (x)
8 * x
Furthermore, I have used parenthesis for both the numerator and the denominator, and the output for the second derivative is incorrect.
> b = D((-1+3*x^2)/(1+x^2) ~x)
> b
function (x)
{
.e1 <- x^2
.e2 <- 1 + .e1
x * (6 - 2 * ((3 * .e1 - 1)/.e2))/.e2
}
> k = D(b~ x)
> k
function (x, t)
0
The correct answer for the second derivative is 8(-3x^2+1)/(1+x^2)^3
https://www.symbolab.com/solver/step-by-step/%5Cfrac%7Bd%7D%7Bdx%7D%5Cfrac%7B8x%7D%7B%5Cleft(1%2Bx%5E%7B2%7D%5Cright)%5E%7B2%7D%7D?or=input
I think you need b(x) ~ x to get your second derivative. That will give you an expression in x that can be differentiated. As is, you are differentiating an expression that doesn’t depend on x, so the derivative is 0.
I might create an issue on GitHub to see if it is possible to emit a useful message in this case.

Understanding code for custom in-place modification function?

I came across this post: http://r.789695.n4.nabble.com/speeding-up-perception-tp3640920p3646694.html from Matt Dowle, discussing some early? implementation ideas of the data.table package.
He uses the following code:
x = list(a = 1:10000, b = 1:10000)
class(x) = "newclass"
"[<-.newclass" = function(x,i,j,value) x # i.e. do nothing
tracemem(x)
x[1, 2] = 42L
Specifically I am looking at:
"[<-.newclass" = function(x,i,j,value) x
I am trying to understand what is done there and how i could use this notation.
It looks to me like:
i is the row index
j is column index
value is the value to be assigned
x is the object under consideration
My best guess would therefore be that i define a custom function for in place modification (for a given class).
[<-.newclass is in class modification for class newclass.
Understanding what happens:
Usually the following code should return an error:
x = list(a = 1:10000, b = 1:10000)
x[1, 2] = 42L
so i guess the sample code does not have any practical use.
Attempt to use the logic:
A simple non-sense try would be to square the value to be inserted:
x[i, j] <- value^2
Full try:
> x = matrix(1:9, 3, 3)
> class(x) = "newclass"
> "[<-.newclass" = function(x, i, j, value) x[i, j] <- value^2 # i.e. do something
> x[1, 2] = 9
Error: C stack usage 19923536 is too close to the limit
This doesnt seem to work.
My question(s):
"[<-.newclass" = function(x,i,j,value) x
How exactly does this notation work and how would I use it?
(I add data.table tag since the linked discussion is about the "by-reference" in place modification in data.table, i think).
The `[<-`() function is (traditionally) used for subassignment, and is, more broadly, a type of replacement function. It is also generic (more specifically, an internal generic), which allows you to write custom methods for it, as you correctly surmised.
Replacement functions
In general, when you call a replacement function, such as ...
foo(x) <- bar(y)
... the expression on the right hand side of <- (so here bar(y)) gets passed as a named value argument to `foo<-`() with x as the first argument, and the object x is reassigned with the result: that is, the said call is equivalent to writing:
x <- `foo<-`(x, value = bar(y))
So in order to work at all, all replacement functions must take at least two arguments, one of which must be named value.
Most replacement functions only have these two arguments, but there are also exceptions: such as `attr<-` and, typically, subassignment.
Subassignment
When you have a subassignment call like x[i, j] <- y, i and j get passed as additional arguments to the `[<-`() function with x and y as the first and value arguments, respectively:
x <- `[<-`(x, i, j, value = y) # x[i, j] <- y
In the case of a matrix or a data.frame, i and j would be used for selecting rows and columns; but in general, this does not need to be the case. A method for a custom class could do anything with the arguments. Consider this example:
x <- matrix(1:9, 3, 3)
class(x) <- "newclass"
`[<-.newclass` <- function(x, y, z, value) {
x + (y - z) * value # absolute nonsense
}
x[1, 2] <- 9
x
#> [,1] [,2] [,3]
#> [1,] -8 -5 -2
#> [2,] -7 -4 -1
#> [3,] -6 -3 0
#> attr(,"class")
#> [1] "newclass"
Is this useful or reasonable? Probably not. But is it valid R code? Absolutely!
It's less common to see custom subassignment methods in real applications, as `[<-`() usually "just works" as you might expect it to, based on the underlying object of your class. A notable exception is `[<-.data.frame`, where the underlying object is a list, but subassignment behaves matrix-like. (On the other hand, many classes do need a custom subsetting method, as the default `[`() method drops most attributes, including the class attribute, see ?`[` for details).
As to why your example doesn't work: remember that you are writing a method for a generic function, and all the regular rules apply. If we use the functional form of `[<-`() and expand the method dispatch in your example, we can see immediately why it fails:
`[<-.newclass` <- function(x, i, j, value) {
x <- `[<-.newclass`(x, i, j, value = value^2) # x[i, j] <- value^2
}
That is, the function was defined recursively, without a base case, resulting in an infinite loop. One way to get around this would be to unclass(x) before calling the next method:
`[<-.newclass` <- function(x, i, j, value) {
x <- unclass(x)
x[i, j] <- value^2
x # typically you would also add the class back here
}
(Or, using a somewhat more advanced technique, the body could also be replaced with an explicit next method like this: NextMethod(value = value^2). This plays nicer with inheritance and superclasses.)
And just to verify that it works:
x <- matrix(1:9, 3, 3)
class(x) <- "newclass"
x[1, 2] <- 9
x
#> [,1] [,2] [,3]
#> [1,] 1 81 7
#> [2,] 2 5 8
#> [3,] 3 6 9
Perfectly confusing!
As for the context of Dowle's "do nothing" subassignment example, I believe this was to illustrate that back in R 2.13.0, a custom subassignment method would always cause a deep copy of the object to be made, even if the method itself did nothing at all. (This is no longer the case, since R 3.1.0 I believe.)
Created on 2018-08-15 by the reprex package (v0.2.0).

Equivalent to let expressions in r

Is there some equivalent to express let expressions in r? As an example take this simple haskell code:
let x = 1 in x + 1
Many thanks in advance.
One equivalent would be a lambda function, which you can define and call in a single statement:
(function(x) x+1)(x = 1)
The first () part defines a function, while the second () part calls that function, supplying the value of 1 for the argument named x.
Here are a few:
x <- 100
# 1
with(list(x = 1), x + 1)
## [1] 2
# 2
local(x + 1, list(x = 1))
## [1] 2
# 2a
local({
x <- 1
x + 1
})
## [1] 2
# 3
eval(substitute(x + 1, list(x = 1)))
## [1] 2
# 4
library(wrapr)
let(c(x = "1"),
x + 1,
subsMethod = "stringsubs",
strict = FALSE)
## [1] 2
x
## [1] 100
Also there is an open issue in the lambda.r package to add let.
If the intent of this is to make x only available in that expression, environments could offer this capability:
#make an environment
myenv <- new.env()
#assign 1 to variable x in our environment
myenv$x <- 1
#evaluate the expression within our environment
with(myenv, x + 1)
#[1] 2
#x only works within our created environment and not on the global environment
#(i.e. the default environment when working on the console)
x + 1
#Error: object 'x' not found
As per #Roland 's comment this can be shortened to local({x <- 1; x + 1}). See ?local.
One equivalent is a lambda function, whereby, you use the
implicit local({ }) within the function body
(this is a slightly improved answer of #ArtemSokolov's answer).
(function() {
x <- 1
x + 1
})()
This is equivalent to
local({
x <- 1
x + 1
})

Create unary operator in R

Is it possible to create a unary operator in R? I know it's possible to create binary operator like this:
setGeneric("%power%", function(x, y) x ^ y)
2 %power% 4
But is it possible to create a unary operator like -. I tried something like:
setGeneric("%-%", function(x) -x)
%-% 3
But it doesn't work
The R parser doesn't support custom unary operators.
A copy of the list of supported operators from the R language definition:
- Minus, can be unary or binary
+ Plus, can be unary or binary
! Unary not
~ Tilde, used for model formulae, can be either unary or binary
? Help
: Sequence, binary (in model formulae: interaction)
* Multiplication, binary
/ Division, binary
^ Exponentiation, binary
%x% Special binary operators, x can be replaced by any valid name
%% Modulus, binary
%/% Integer divide, binary
%*% Matrix product, binary
%o% Outer product, binary
%x% Kronecker product, binary
%in% Matching operator, binary (in model formulae: nesting)
< Less than, binary
> Greater than, binary
== Equal to, binary
>= Greater than or equal to, binary
<= Less than or equal to, binary
& And, binary, vectorized
&& And, binary, not vectorized
| Or, binary, vectorized
|| Or, binary, not vectorized
<- Left assignment, binary
-> Right assignment, binary
$ List subset, binary
(The parser supports also the binary operator := which is not documented here, because it is not used by base R.)
Note that the only custom operators ("%x% Special binary operators, x can be replaced by any valid name") are binary.
So, your only option is overloading an existing unary operator respectively writing a method for it.
Although I am not familiar with setGeneric, I can answer the question
Is it possible to create a unary operator in R?
Yes, sort of, but not really. You can fake it:
# LET'S USE A BINARY OPERATOR TO DEFINE A UNARY OPERATOR:
# THE SYMBOL /*/<- IS SUPPOSED TO LOOK LIKE PERCENT-WILDCARD-PERCENT--ASSIGNMENT-ARROW
`%/*/<-%` <- function ( name , FUN , safe = TRUE ) {
`%//%` <- paste0
NAME <- "%" %//% name %//% "%"
PARENT <- parent.frame ()
if ( safe && exists ( NAME , PARENT ) )
stop ( NAME %//% " exists." )
assign (
x = NAME ,
value = function ( x , ignored ) FUN ( x ) ,
envir = PARENT ) }
.. <- NULL # THIS IS WHAT I MEAN BY FAKING IT...
"-" %/*/<-% `-` # ... `%-%` IS ACTUALLY A BINARY OPERATOR....
1 %-%.. # ... IN THIS CALL, `..` IS THE SECOND ARGUMENT.
# [1] -1
1 %-%.. %-%..
# [1] 1
"t" %/*/<-% `t`
m <- matrix(1:4, 2)
m
# [,1] [,2]
# [1,] 1 3
# [2,] 2 4
m %t%..
# [,1] [,2]
# [1,] 1 2
# [2,] 3 4
"-" %/*/<-% `-`
# Error in "-" %/*/<-% `-` : %-% exists.
i <- floor ( runif ( 9 , min = 1 , max = 10 ) )
i
# [1] 2 3 2 1 7 3 9 5 9
unique(i)
# [1] 2 3 1 7 9 5
"u" %/*/<-% function ( x ) sort ( unique ( x ) )
i %u%..
# [1] 1 2 3 5 7 9

Define `+=` in R [duplicate]

Does R have a concept of += (plus equals) or ++ (plus plus) as c++/c#/others do?
No, it doesn't, see: R Language Definition: Operators
Following #GregaKešpret you can make an infix operator:
`%+=%` = function(e1,e2) eval.parent(substitute(e1 <- e1 + e2))
x = 1
x %+=% 2 ; x
R doesn't have a concept of increment operator (as for example ++ in C). However, it is not difficult to implement one yourself, for example:
inc <- function(x)
{
eval.parent(substitute(x <- x + 1))
}
In that case you would call
x <- 10
inc(x)
However, it introduces function call overhead, so it's slower than typing x <- x + 1 yourself. If I'm not mistaken increment operator was introduced to make job for compiler easier, as it could convert the code to those machine language instructions directly.
R doesn't have these operations because (most) objects in R are immutable. They do not change. Typically, when it looks like you're modifying an object, you're actually modifying a copy.
Increment and decrement by 10.
require(Hmisc)
inc(x) <- 10
dec(x) <- 10
We released a package, roperators, to help with this kind of thing. You can read more about it here: https://happylittlescripts.blogspot.com/2018/09/make-your-r-code-nicer-with-roperators.html
install.packages('roperators')
require(roperators)
x <- 1:3
x %+=% 1; x
x %-=% 3; x
y <- c('a', 'b', 'c')
y %+=% 'text'; y
y %-=% 'text'; y
# etc
We can override +. If unary + is used and its argument is itself an unary + call, then increment the relevant object in the calling environment.
`+` <- function(e1,e2){
# if binary `+`, keep original behavior
if(!missing(e2)) return(base::`+`(e1, e2))
# if inner call isn't unary `+` called on language object,
# keep original behavior
inner_call <- substitute(e1)
inner_call_is_plus_on_lng <-
length(inner_call) == 2 &&
identical(inner_call[[1]], quote(`+`)) &&
is.language(inner_call[[2]])
if(!inner_call_is_plus_on_lng) return(base::`+`(e1))
eval.parent(substitute(X <- X + 1, list(X = inner_call[[2]])))
}
x <- 10
++x
x
#> [1] 11
other operations don't change :
x + 2
#> [1] 13
x ++ 2
#> [1] 13
+x
#> [1] 11
x
#> [1] 11
I can't really recommend it since you're messing with primitives which are optimised for a reason.
We can also use inplace
library(inplace)
x <- 1
x %+<-% 2
If you want to use i++ in an array to increment the index, you can try i <- i + 1, for example,
k = 0
a = 1:4
for (i in 1:4)
cat(a[k <- k + 1], " ")
# 1 2 3 4
but here <- can NOT be replaced with =, which does not update the index,
k = 0
a = 1:4
for (i in 1:4)
cat(a[k = k + 1], " ")
# 1 1 1 1
since = and <- are not always equivalent, as said in ?`<-`

Resources