0

I make a new function:

  newFunction <- function (varX) {

  lst_a <- c("aa", "bb", "cc")
  lst_b <- c("dd", "ee", "ff")
  lst_c <- c("gg", "hh", "ii")

  ifelse(varX %in% lst_a , x.out <- "List A" , x.out <- "Other List" )
  ifelse(varX %in% lst_b , x.out <- "List B" , x.out )
  ifelse(varX %in%  lst_c , x.out <- "List C" , x.out)

  return(x.out)

 }

When I test the function it works well. But when I apply it to a dataframe it does not work:

     df <- as.data.frame(c("aa","cc","kk", "nn"))
    df$new <- newFunction((df[,1]))

I expected to get "List A", "List A", "Other list", "Other List" - but no such luck have I, and left with me is "Other list", "Other List", "Other list", "Other List"

  • 1
    You are asking if the whole vector df[,1] is in any of the lists. I think you need to ask the question for each element of it. – Cleland Nov 28 '18 at 14:21
  • true.. apply would be the right function to apply here.. – Soren Christensen Nov 28 '18 at 14:22
  • Like this: sapply(df[,1], newFunction) – Cleland Nov 28 '18 at 14:23
  • thx.. sometimes its right in front of me, and i cant see it. – Soren Christensen Nov 28 '18 at 14:24
  • I wish I could downvote all of these comments. @Cleland: `%in%` is vectorized, `varX %in% lst_a` **is** "asking the question" for each element. @Soren and Cleland, `apply` is not needed, vectorization is needed. The problem is that `ifelse` (which is vectorized) is being used as if it's not, doing assignment within `ifelse()` (bad) rather than treating `ifelse` as a function that returns a value - a vector of the same length as the input. See my answer. – Gregor Thomas Nov 28 '18 at 15:13

2 Answers2

1

You could try either

sapply (df[,1], newFunction)

or

map(df[,1], newFunction)
1

Do it like this:

newFunction <- function (varX) {
   lst_a <- c("aa", "bb", "cc")
   lst_b <- c("dd", "ee", "ff")
   lst_c <- c("gg", "hh", "ii")

   x.out = ifelse(varX %in% lst_a , "List A" , 
             ifelse(varX %in% lst_b , "List B",
               ifelse(varX %in%  lst_c , "List C" , "Other List")))    
   return(x.out)    
 }

Now it is vectorized and you can do df$new <- newFunction(df[,1]) and it is much more efficient.

I'd strongly recommend reading this R-FAQ to understand ifelse vs if(){}else{}.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294