In R, how to define a function with undefined arguments of the same nature

3

Hi, I'm defining one function from another. However, I want to define my new function with several arguments of the same nature. For example

My basic function is well-defined

funcaobase(data, argumento1)

But my new function I want you to do this several times in the argument. That is, at the time of defining, something like

NovaFuncao(data, argumento1, argumento2, argumento3, ...)
{

  data<- funcaobase(data, argumento1)
  data<- funcaobase(data, argumento2)     
  data<- funcaobase(data, argumento3)
  ...

  return(data)
 }  

But I would like a function so that it works

 NovaFuncao(data, argumento1, argumento2, argumento3, argumento4 , argumento5)

I do not know how to do this.

PS: Actually I want to modify this question that I asked before. so that I can modify several levels at the same time - staying in the same variable - ie, something like function (dat, variable, fixed, levls1, newLevls2, levls2, newLevls2, levls3, newLevls3, ...) In R, create a function to change some levels of a variable

    
asked by anonymous 02.03.2015 / 20:39

1 answer

4

First responding to your specific problem, based on your comment.

The sample function that you put handles "non-standard" evaluation, which makes it harder to program with functional (like lapply ). So, I'll create another equivalent function to illustrate your case.

The function below takes a text vector and replaces certain words (or regular expressions) with others:

mgsub <- function(replacement, pattern, x){
  aux <- data.frame(replacement, pattern)
  for(i in 1:nrow(aux)) x <- gsub(aux[i,1], aux[i,2], x)
  x
}

In the example of iris data, we will change the species "setosa" and "virginica" to "new":

iris$Species <- mgsub(c("setosa", "virginica"), "novo", iris$Species)

Okay, we have a function that does this for one vector at a time. Now we only need a function that does this for multiple vectors at the same time. We will therefore create a new function with Vectorize() .

NovaFuncao <- function(dados, variaveis, levels, novosLevels){
  dados[variaveis] <- Vectorize(mgsub, SIMPLIFY = FALSE)(levels, novosLevels, dados[variaveis])
  dados
}

Now our function accepts a data.frame , a vector with the name of the variables that will be replaced, a list with the old levels and a list with the new levels. Creating a test database:

df <- data.frame(fator1 = c("a", "b", "c"),
                 fator2 = c("f", "g", "h"),
                 fator3 = c("i", "j", "k"))
df
  fator1 fator2 fator3
1      a      f      i
2      b      g      j
3      c      h      k

NovaFuncao(df, 
           variaveis = c("fator1", "fator2"), 
           levels = list(c("a", "b"), 
                         c("f")),
           novosLevels = list(c("novo1", "novo2"),
                              c("novo3"))
           )
 fator1 fator2 fator3
1  novo1  novo3      i
2  novo2      g      j
3      c      h      k

Well, keeping the previous generic answer below:

Suppose this is your base function:

funcaobase <- function(data, argumento1){
  paste(data, argumento1)
}

Testing the function:

data <- "teste"
funcaobase(data, 1)
[1] "teste 1"

What you want is to vector it in argumento1 (the paste function is already vectorized, so you would not have to do this, but just for illustration let's assume it was not).

NovaFuncao <- Vectorize(funcaobase, vectorize.args = "argumento1", SIMPLIFY = FALSE)

Now you can use several arguments instead of just one:

argumentos <- 1:5
NovaFuncao(data, argumentos)
[[1]]
[1] "teste 1"

[[2]]
[1] "teste 2"

[[3]]
[1] "teste 3"

[[4]]
[1] "teste 4"

[[5]]
[1] "teste 5"

In more detail, Vectorize uses lapply or mapply . For example, you can do the same thing with lapply in arguments holding data fixed:

lapply(argumentos, funcaobase, data=data)
[[1]]
[1] "teste 1"

[[2]]
[1] "teste 2"

[[3]]
[1] "teste 3"

[[4]]
[1] "teste 4"

[[5]]
[1] "teste 5"

So you can turn this command into a new function:

NovaFuncao <- function(data, argumentos){
  lapply(argumentos, funcaobase, data=data)
}

NovaFuncao(data, argumentos)
[[1]]
[1] "teste 1"

[[2]]
[1] "teste 2"

[[3]]
[1] "teste 3"

[[4]]
[1] "teste 4"

[[5]]
[1] "teste 5"

That's the basic logic. You can also do this with a% loop% or using other functions of the for family depending on the case.

    
02.03.2015 / 22:57