Using str() appears to change the evaluation why?
MWE:
f1 <- function(x, y = x) {
str(y)
x <- x + 1
y }
f1(1) # result is 1
f2 <- function(x, y = x) {
x <- x + 1
y }
f2(1) # result is 2
Why does this happen? I tried to use pryr library to debug but can not see the references being updated.
Lazy evaluation. It is about when y = x is evaluated. It is evaluated right before the first statement that uses y.
## f1
y <- x
str(y) ## first use of y
x <- x + 1
y
## f2
x <- x + 1
y <- x
y ## first use of y
Related
Consider this function plus_x:
y <- 1
plus_x <- function(input, x = y){
return(input + x)
}
here the y default-value for x is evaluated during the function call.
If I change y later on, I am also changing the functions behaviour.
y <- 1
plus_x <- function(input, x = y){
return(input + x)
}
y <-10
plus_x(1)
# > 11
Is there a way to "cement" the value for y to the state it was during the function definition?
Target:
y <- 1
plus_x <- function(input, x = y){
# y is now always 1
return(input + x)
}
y <-10
plus_x(1)
# > 2
1) local Surround the function with a local that saves y locally:
y <- 1
plus_x <- local({
y <- y
function(input, x = y) input + x
})
y <-10
plus_x(1)
## [1] 2
2) generator Another approach is to create a generator function. This has the advantage that multiple different functions with different y values could be easily defined. Look at demo("scoping", package = "base") for more examples of using scoping.
gen <- function(y) {
force(y)
function(input, x = y) input + x
}
y <- 1
plus_1 <- gen(y)
y <-10
plus_1(1)
## [1] 2
y <- 2
plus_2 <- gen(y)
y <- 10
plus_2(1)
## [1] 3
You could define the function using as.function so that the default value is evaluated at the time of function construction.
y <- 1
plus_x <- as.function(list(input = NULL, x = y, quote({
return(input + x)
})))
plus_x(1)
#> [1] 2
y <-10
plus_x(1)
#> [1] 2
I am fairly new to programming in R and I am wondering why this does not work:
w <- c(1,0)
deriv(~x^2+y,c("x","y"),function.arg = TRUE)(w)
I really want to apply the function produced by deriv() on a variable w.
Maybe some background on how to deal with these kinds of "macros" might be helpful...
We can use do.call and pass the 'w' as a list of arguments
do.call(deriv(~x^2+y,c("x","y"),function.arg = TRUE), as.list(w))
Your function exposes two non-default parameters but you only pass one argument. Below would work, if this is your intention:
w <- c(1,0)
deriv( ~ x^2 + y, c("x","y"), function.arg = TRUE)(w, w)
# [1] 2 0
# attr(,"gradient")
# x y
# [1,] 2 1
# [2,] 0 1
Alternatively, set up a default parameter:
w <- c(1,0)
deriv( ~ x^2 + y, c("x","y"), function.arg = function(x, y=2){})(x=w)
# [1] 3 2
# attr(,"gradient")
# x y
# [1,] 2 1
# [2,] 0 1
# MORE READABLE VERSION WITH identity()
myfunc <- deriv( ~x^2 + y, c("x","y"), func = function(x, y=2) identity(x,y))
myfunc(x=w)
I'd like to do this:
for example, i have one data.table as:
dt <- data.table(a=1:3, b=5:7, c=10:8)
# a b c
#1: 1 5 10
#2: 2 6 9
#3: 3 7 8
and i want to pass the environment of one row per time to a function, for example:
f <- function(a,b,c){
x <- a*b
y <- a*c
z <- a/b
return( x + y + z)
}
I know i could use in this case mapply to solve this multivariate function, but in my real need i have a function that manipulate almost 150 variables of a data.table, and i don't want to assign the variable's names one by one. I also tried some .SD manipulatations, but it didn't work either.
I would like something that i pass the number of data.table row, and inside the function they get the objects a, b and c in the data.table environment.
Something similar to this:
f <- function(row_id){
# set function parent env as data.table[row_id]
# and *a = data.table[row_id, a]* and successively to b and c...
x <- a*b
y <- a*c
z <- a/b
return( x + y + z)
}
One way would be to adapt the function to take in a given data.table and a row and output your x + y + z:
f <- function(dataTable,row_id){
a <- dataTable[row_id,a]
b <- dataTable[row_id,b]
c <- dataTable[row_id,c]
x <- a*b
y <- a*c
z <- a/b
return( x + y + z)
}
If you input f(dt) it'll give youall of the x+y+z values, or if you give it f(dt,1), it'll return values for the first row only.
EDIT:
Assuming that you're column names are the variable names you want to assign, you could try this:
f <- function(dataTable,row_id){
for(i in colnames(dataTable)){
assign(paste(i,"",sep=""), dataTable[row_id,..i])
}
x <- a*b
y <- a*c
z <- a/b
return( x + y + z)
}
I'm trying to create a custom function that has an arugment that requires the arguments of another function. For instance, something like this:
funct1 <- function(x,y,z){
x + y + z
}
funct2 <- function(funct1, multiplier) {
print("first arg is ": [funct1 x arg]
print("second arg is ": [funct1 y arg]
print("third arg is ": [funct1 z arg]
}
first <- funct1(1,2,3)
funct2(first1, 2)
#first arg is 1
#second arg is 2
#third arg is 3
first <- funct1(3,4,5) #12
funct2(first1, 2)
#first arg is 3
#second arg is 4
#third arg is 5
If you want to be able to pass the function and arguments into the new function without having to define what those arguments are then you can use ...
f1 <- function(x, y, z){x + y + z}
f2 <- function(x, y){x * y}
doubler <- function(func, ...){
func(...) * 2
}
f1(1, 2, 3)
# 6
doubler(f1, 1, 2, 3)
# 12
f2(3, 4)
# 12
doubler(f2, 3, 4)
# 24
You simply need to have the same variable in each. What is the end game for this though?
funct1 <- function(x,y,z){
x + y + z
}
funct2 <- function(x,y,z) {
funct1(x,y,z) * 2
}
funct2(3,4,5)
> 24
Contrast the following two code snippets:
1)
> y <- 1
> g <- function(x) {
+ y <- 2
+ UseMethod("g")
+ }
> g.numeric <- function(x) y
> g(10)
[1] 2
2)
> x <- 1
> g <- function(x) {
+ x <- 2
+ UseMethod("g")
+ }
> g.numeric <- function(y) x
> g(10)
[1] 1
In the first snippet, g.numeric's free variable (namely, "y") is evaluated in g's local environment, whereas in the second snippet, g.numeric's free variable (namely "x") is evaluated in the global environment. How so?
As it says in Writing R Extensions:
A method must have all the arguments of the generic, including … if the generic does.
Your second example does not (g(x) vs g.numeric(y)). If you redefine g <- function(y), everything works the same as your first example.
> x <- 1
> g <- function(y) {
+ x <- 2
+ UseMethod("g")
+ }
> g.numeric <- function(y) x
> g(10)
[1] 2