1

I'm modifying some previous code I got thanks to @BrianDiggs: [](

Here's my reproducible code, as my actual code uses a data file and is much more involved based on various ifelse cases. This produces the same error:

First, unmodified and working

library(plyr)

df <- data.frame(name = LETTERS[1:3], var1 = c(1,5,10), var2 = c(2, 4, 6))

generator <- function(name, var1, var2) {

function(varA, varB) {

  ifelse(varA + varB < 10,
    10,
    100)
}

}

funs <- mlply(df, generator)

interactions <- expand.grid(one = seq(0, 20, by=5), two = seq(0, 20, by=5))

table <- ldply(funs, function(f) {
  data.frame(varA=interactions$one, varB=interactions$one,
  result=f(interactions$one, interactions$two))
})

I don't really understand plyr at all... but it's working. From my best guess, I create my input values and then plyr creates a sort of object with a function definition in it (funs). Then I create my second layer of values and run the second function on the whole table of combinations.


Modified, not working
In any case, I want to have two different functions depending on cases. Here's what I tried:

library(plyr)

df <- data.frame(name = LETTERS[1:3], var1 = c(1,5,10), var2 = c(2, 4, 6))

generator <- function(name, var1, var2) {

ifelse(name == "A",

function(varA, varB) {

  ifelse(varA + varB < 10,
    10,
    100)
},

function(varA, varB) {

  varA + varB

})

}

funs <- mlply(df, generator)

interactions <- expand.grid(one = seq(0, 20, by=5), two = seq(0, 20, by=5))

table <- ldply(funs, function(f) {
  data.frame(varA=interactions$one, varB=interactions$one,
  result=f(interactions$one, interactions$two))
})

For this, I get, Error: Object of type 'closure' is not subsettable


I also tried doing the ifelse() split inside the second function:

library(plyr)

df <- data.frame(name = LETTERS[1:3], var1 = c(1,5,10), var2 = c(2, 4, 6))

generator <- function(name, var1, var2) {

function(varA, varB) {

ifelse(name == "A",

  "foo",

  ifelse(varA + varB < 10,
    10,
    100))

}

}

funs <- mlply(df, generator)

interactions <- expand.grid(one = seq(0, 20, by=5), two = seq(0, 20, by=5))

table <- ldply(funs, function(f) {
  data.frame(varA=interactions$one, varB=interactions$one, result=f(interactions$one, interactions$two))
})

For this, I get In '[<-.factor'('*tmp*', ... : invalid factor level, NAs generated.


If I replace ifelse(name == "A") with ifelse(0 < 1), I get, as expected all results as foo. If I replace with ifelse(name == 1), I get all results of 10, which is odd because there's numerous cases where varA + varB > 10.

Interestingly, I added another column to df of criteria = c(1, 5, 10). I can't do ifelse(criteria > 1), but I can do ifelse(varA > criteria). Why wouldn't it allow a comparison to a static number, but it would allow for a comparison between row variables?


Anyway, my hope is to be able to do something like this:

generator <- function(var1, var2, ... , varN) {

function(varA, varB) {

ifelse(criteria based on any of var1 ... varN,

   do a bunch of stuff,

do different stuff if criteria not met)

}

}
Hendy
  • 10,182
  • 15
  • 65
  • 71
  • I think you may simply be confusing `ifelse` and plain old `if(){}else{}` You're probably trying to use the former when you should be using the latter. – joran Oct 28 '12 at 19:35
  • @joran Didn't even know about a difference (R noob) :) Feel free to write up your comment in an answer. I replaced the first condition with `if(name == "A") {do stuff version 1} else {do stuff version 2}` and it's working (actually, I did the equivalent in my real code and it's working; I didn't actually test it above, but assume that was the issue. Is there a good explanation of what was happening with `ifelse()` ? – Hendy Oct 28 '12 at 20:02
  • `ifelse()` returns a value with the same "shape" as the object you passed it to condition. If you pass it a vector, it returns a vector, a matrix, returns a matrix, a data.frame a matrix. – Brandon Bertelsen Oct 28 '12 at 20:18
  • @BrandonBertelsen So I wanted to evaluate a single instance based on the current row's data so I needed `if()` but the rest of the code needs `ifelse()` to work on the data frame? Would that be accurate? Still not entirely sure why the df-based evaluation of the rest of my code works, then, and the bulk evaluation of another condition didn't? Then again, I find `plyr` confusing as hell and still don't really get what Brian did in the original code... but it works, so I'm using it and mostly able to futz with it successfully :) – Hendy Oct 28 '12 at 20:28
  • If you give ifelse() a data.frame it will return a matrix, which won't be of the correct closure type for future operations if you were expecting a vector of data. Use if {} else {} instead. Actually, always. It functions much more intuitively. – Brandon Bertelsen Oct 28 '12 at 20:48

0 Answers0