简体   繁体   中英

How to revalue elements in factor based on values of arguments, passed to the function in R

Good morning,

Could you help me with the following problem? I have a function to which I pass certain values that are levels in a factor. I would like to revalue levels in factor, based on this values.

For example, if I want to revalue levels in factor my_factor ("cats" -> "animals", "pines" -> "trees"), I use: my_factor <- revalue(my_factor, c("cats"="animals", "pines"="trees")) . But now I want to revalue levels, based on values of arguments, passed to the function :

myFunction(..., member1 = "cats", member2 = "pines") {
my_factor <- revalue(my_factor, c(member1="animals", member2="trees"))
}

This fragment of code isn't working ( Error: The following from values were not present in x : member1, member2 ).

Please tell me how to do it correctly? Perhaps I need to use something other than revalue .

Good regards, Poecile

You reference plyr , but that package is obsolete and its use is generally not recommended. I'm not going to attempt a solution in the dplyr manner, since I don't have a sufficient command of it's various levels of abstraction.

The base function levels<- will do this cleanly. When you do something like:

levels(fac)[some_index] <- "something"

You change the print value of that level without changing the underlying pattern of factor integers that carry the information. So use `levels(fac), once to get the current values of the levels to create a logical index to use inside "[" and again on the "outside" to do the reassignment:

levels(fac)[ levels(fac) == "cats"] <- "animals"
levels(fac)[ levels(fac) == "pines"] <- "trees"

You are actually using two different functions: levels<- (on the outside) and levels (on the inside). To make this process into a function that can handle an arbitrary number of reassignments, you would want the reassignment pairs to be carried in a list of lists so you could iterate over the pairs. Your current request is attempting to use a language-like expression such as "cats" = "animals" , but that would create a parameter named cats with a value of "animals"

reval <- function(x)(fac, reassign) {
             lapply(reassign, function(fac, pair) {
                       levels(col)[levels(col)==pair[[1]]] <-pair[[2]]}
                                      return(fac) }

And you would call it like this:

facname <- reval ( facname, list( list("curlev1", "newlev1"),
                                  list("curlev2", "newlev2")) )  )

If you have an example off the example naming you used "my_factor ("cats" -> "animals", "pines" -> "trees")" then test it with

 my_factor <- reval( my_factor, reassign = list (list("cats" , "animals"), 
                                           list("pines" , "trees") ) )

If it doesn't work then you should post R code to create an example that can be used for further development and testing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM