I am trying to write a function that would generate first n terms with the given equation.
For example: f(x_2)= x_1*r+3, and x_n = f(x_(n-1)
Here is my code:
super = function(x,r,n){
x[n] = r*x+3
x1=seq(x,x[n],,n)
return(x1)
}
When I try to run it I keep getting: Error in super(0.6, 2, 100) : could not find function "x".
But if I make a basic code like:
n=88
x=0.6
x1 = seq(x,100,,n)
everything works
Thanks in advance for any inputs
We can slice the input and apply function on the new slice.
getFirstN = function(arr, func, n){
slice = arr[1:n]
return(lapply(slice, func))
}
e.g.:
square = function(x) {
return(x * x)
}
example = c(1, 2, 3, 4)
print(getFirstN(example, square, 2))
1, 4 # the output
Related
I have created a function, say myfunc, which has 4 parameters, say para1, para2, para3 and para4. In my problem, para1 is a matrix, para2 is a real number, para3 is a vector, and para4 is a real number. The function returns a list. I have defined the function in the following manner :
myfunc <- function(para1, para2, para3 = NULL, para4 = 100){
Body ## Body of the function
return(list("A" = a, "B" = b, "C" = c)
}
Now, let lambda <- c(2,3,6,10). I am trying to write a code so that the function outputs the following :
myfunc(my_data, 2, my_vec, 100)
myfunc(my_data, 3, my_vec, 100)
myfunc(my_data, 6, my_vec, 100)
myfunc(my_data, 10, my_vec, 100)
This can be easily done by a for loop, but I was thinking if we can use apply or sapply or tapply function for this purpose. So, keeping the other parameters fixed, I want outputs of the same function with different values (viz. the values in lambda) of para2. Can this be done ?
I found a quite similar question here, and saw some answers. I followed those answers, but I'm getting an error. I wrote the following code :
myfunc <- function(para1, para2, para3 = NULL, para4 = 100) { Body }
para1 <- my_data
para3 <- my_vec
para4 <- 100
lambda <- c(2,3,6,10)
sapply(lambda, myfunc, para1=para1, para3, para4=para4)
Can I please get some assistance ? Thanks in advance.
We can use lapply to loop over the lambda
lapply(lambda, function(x) myfunc(my_data, x, my_vec, 100))
If we are not using lambda function
lapply(lamdba, myfunc, para1 = my_data, para3 = my_ec, para4 = 100)
Supposed I have an arbitrary function
foo = function(a,b) {a+b}
How can I iterate this function onto itself n times?
foo(foo(foo(foo(x, 1), 2), 3, 4)
I am looking at purrr:compose but it doesn't look hopeful for arbitrary n. purrr:reduce feels like it will come into play also... but I'm stumped.
Here is a pure purrr version, that is really functional, as you said reduce comes in handy here, since compose is just a function and functions are just elements you can reduce functions by composing them. To just fill one argument use partial.
foo_n <- reduce(map(1:n, ~partial(foo, b=.x)), compose)
You can also just append results of each foo(a,b) function into a numeric vector and then pick up the last result.
Let's x = 1 and bs are elements of 1:4:
x = 1
n = 4
out = vector("numeric")
steps = seq(1, 4, by = 1)
for( b in steps){
## initial value
if (length(out) == 0){
out = append(out, values = foo(x, b) )
}else{
out = append(out, values = foo( tail( out, 1), b) )
}
}
tail(out, 1)
I am trying to do something much more complex than my example below, but the basic idea is encapsulated in this example:
pass_thru <- function(FUN,params){
n <- length(FUN)
out <- list()
for(i in 1:n){
temp <- get(FUN[i],mode="function")
out[[i]] <- temp(params[[i]])
}
return(out)
}
fun1 <- function(x,y,z){
x+y+z
}
fun2 <- function(l,m,n){
l*m*n
}
FUN = c("fun1","fun2")
params = list(c(x=1,y=2,z=3,
l=4,m=5,n=6))
pass_thru(FUN,params)
The passing and parsing of FUN within pass_thru() works fine, but passing params as a list only works if every element of params is a single value (only one parameter passed to each function of FUN). I am not sure how to get multiple parameters to each function in FUN to be passed to the appropriate FUN.
What I really want to be able to do is to pass some of the parameters to each FUN in my call to pass_thru(), and have the body of pass_thru calculate the rest of the parameters to be passed to fun1 and fun2.
I am trying to create a flexible architecture upfront for large-scale data analysis, so having the ability to pass functions as well as any or all of those functions' parameters to other functions would be of great help. Thank you for any insights you have into this question!
Use do.call like this and also fix params as shown:
params <- list(list(x = 1, y = 2, z = 3), list(l = 4, m = 5, n = 6))
pass_thru <- function(FUN, params) Map(do.call, FUN, params)
pass_thru(FUN, params)
giving:
$fun1
[1] 6
$fun2
[1] 120
If you really did want:
params2 <- list(x = 1, y = 2, z = 3, l = 4, m = 5, n = 6)
then try this noting that the params[intersect(...)] part picks out the relevant parameters for the function call:
pass_thru2 <- function(FUN, params) {
runf <- function(f) do.call(f, params[intersect(names(params), names(formals(f)))])
lapply(FUN, runf)
}
pass_thru2(FUN, params2)
giving the same result.
Example:
require(data.table)
example = matrix(c(rnorm(15, 5, 1), rep(1:3, each=5)), ncol = 2, nrow = 15)
example = data.table(example)
setnames(example, old=c("V1","V2"), new=c("target", "index"))
example
threshold = 100
accumulating_cost = function(x,y) { x-cumsum(y) }
whats_left = accumulating_cost(threshold, example$target)
whats_left
I want whats_left to consist of the difference between threshold and the cumulative sum of values in example$target for which example$index = 1, and 2, and 3. So I used the following for loop:
rm(whats_left)
whats_left = vector("list")
for(i in 1:max(example$index)) {
whats_left[[i]] = accumulating_cost(threshold, example$target[example$index==i])
}
whats_left = unlist(whats_left)
whats_left
plot(whats_left~c(1:15))
I know for loops aren't the devil in R, but I'm habituating myself to use vectorization when possible (including getting away from apply, being a for loop wrapper). I'm pretty sure it's possible here, but I can't figure out how to do it. Any help would be much appreciated.
All you trying to do is accumulate the cost by index. Thus, you might want to use the by argument as in
example[, accumulating_cost(threshold, target), by = index]
I wrote a function that operates on a single vector. Sometimes I want to use that function on whole data.frame. I can accomplish that by using sapply across the relevant variables, but now I want contain and direct the function using S3 methods.
First, the setup:
df_test <- data.frame(x = c(1, 2, 3, 4, 5),
y = c(6, 7, 8, 9, 10),
z = c(11, 12, 13, 14, 15))
adder <- function(x, from, to) {
if(is.null(ncol(x))) {
x <- structure(list(x = x, from = from, to = to), class = "single")
} else {
x <- structure(list(x = x, from = from, to = to), class = "multiple")
}
UseMethod("adder", x)
}
adder.single <- function(x, from, to) {
x <- x + (from - to) # just some random operation here - the real function does more
x
}
adder.multiple <- function(x, from, to) {
x <- sapply(x, function(y) {
y <- structure(list(x = y, from = from, to = to), class = "single");
UseMethod("adder", y) })
x
}
So on a single vector, the function works:
> adder(df_test[,1], 2, 4)
[1] -1 0 1 2 3
But passing the entire data.frame does not:
> adder(df_test, 2, 4)
Error in from - to : 'from' is missing
It's clear to me what the problem is - adder detects that we're looking at a whole data.frame, uses the "multiple" method, which then calls the "single" method and arguments from and to are not being passed along.
I read Hadley Wickham's OOP Field Guide and Advanced Programming by Nicolas Christian, but it ain't clickin' for me. I welcome a completely different approach, as long as it uses S3 methods because part of this exercise is for me to learn how to use them.
Simply call adder and S3 dispatch will do the right and call the right function.
adder.multiple <- function(x, from, to) {
sapply(x, adder,from,to)
}
You should not define the generic adder twice ( the call to UseMethod).