First by answering your specific problem, based on your comment.
The example function you put up handles "non-standard" Evaluation, which makes it harder to program with functional (such as the lapply
). Thus, I will create another equivalent function to illustrate your case.
The function below takes an array of texts 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 data example iris
, let’s exchange the species "setosa" and "virginica" for "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 just 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
, an array 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
Good, keeping down the previous generic response:
Suppose this is your basic 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 on argumento1
(the function paste
is already vectored, so you wouldn’t need to do this, but just for illustration let’s assume that it wasn’t).
NovaFuncao <- Vectorize(funcaobase, vectorize.args = "argumento1", SIMPLIFY = FALSE)
Now you can use several arguments instead of 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 the lapply
or mapply
. For example, you can do the same thing with a lapply
in arguments keeping 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"
This is the basic logic. You can do this too with a for
loop or using other family functions apply
depending on the case.
Notice that in your
NovaFuncao
you give, in each line, a new value todata
, so that you replace the value to each new row and therefore, yourreturn(data)
will only return the last value associated withdata
. That’s exactly what you intend?– Bernardo
I give a new value, but I would not like this feat to be lost.
– orrillo
If you want it to return all the values, just create a list that stores these values and return the list to the end. If you can give us a reproducible example, it is much easier to help you. The solution may depend, for example, on your data structure (
data
is a data.frame? an array? a list? ) and what its function does.– Bernardo
There is no way to use the three points (...) to avoid repeating the arguments?
– orrillo
Come on. Actually I want to modify this question that I asked before. so that I can modify several levels at the same time, the u is, something like Function(dat, variable, levls1, newLevls2 , levls2, newLevls2) http://answall.com/questions/48767/em-r-crea-uma-fun%C3%A7%C3%A3o-to-change-some-levels-of-a-variable
– orrillo