4

I have a probability tables stored as arrays (outputted by bnlearn). The number of dimensions is always equal to the number of parents + 1. I always want to fetch the first the dimension and the dimnames of the remaining dimensions is stored in vals below.

Right now, I'm doing this:

vals = avatar[cpt$parent] # c('a','b')
eval_str = paste( "cpt$prob[,\'"
                , paste(vals, collapse="\',\'")
                , "\']", sep=""
                )
row = eval(parse(text=eval_str))

In the three dimensional case the code evals to this: row=cpt$prob[,'a','b']

Any idea on how to do this without using eval?

Further Explanation

I would like to subset an array by a variable with the index to subset by. For example:

a1 <- array(1:81, c(3,3,3,3))

I can subset with a1[,2,2,3] directly to get 67 68 69. But if I had a variable vals <- c(2,2,3) and try a1[,vals] I get an error. Or if I try a1[vals] it will evaluate to the equivalent of a1[c(2,2,3)].

I have also tried do.call since it allows for do.call('[', ...). Or with mapply(function(...) a1[...], ..) to no avail.

I would like to have a variable of indices and subset based on those. But NOT the positions as one would normally do.

The issue appears to be in the argument structure of '[' which is x[i, j, ...]. I'm looking for j and ... to be supplied by an outside variable.

For now, I am using the eval(parse(.. method to specify the spacing and comma placement. I can then turn a1[,vals] into a1[,2,2,3] but I would like to avoid that method.

Pierre L
  • 28,203
  • 6
  • 47
  • 69
  • 2
    Not sure what's going on here, but `eval(parse(text=x))` is (almost?) always the wrong approach. Here's guidance on asking a clearer question, that can be reproduced: http://stackoverflow.com/a/28481250/1191259 Also, your question should have a question mark, right? – Frank Oct 07 '15 at 17:38
  • This is a good question. I've tried some solutions but can't find any yet. – Pierre L Oct 07 '15 at 18:25
  • 1
    @PierreLafortune Care to add a reproducible example illustrating what you think is being asked? – Josh O'Brien Oct 07 '15 at 18:32
  • @JoshO'Brien I added an expansion. OP please chime in if you would like to clarify more/differently. – Pierre L Oct 07 '15 at 18:49

1 Answers1

4

As I understand it, you have an indexing vector:

vals <- c(2, 2, 3)

You want to know how to convert this into the following (without using eval):

a1[,2,2,3]
# [1] 67 68 69

Note that this is the same as the following:

"["(a1, , 2, 2, 3)
# [1] 67 68 69

Which can be performed with:

do.call("[", c(list(a1, substitute()), as.list(vals)))
# [1] 67 68 69
josliber
  • 43,891
  • 12
  • 98
  • 133
  • That was the missing piece `substitute()`. Great answer – Pierre L Oct 07 '15 at 19:13
  • Thanks! This works! `vals` needed to be appended like this: `do.call("[", append(list(dat, substitute()), vals))` – Marcus Walz Oct 07 '15 at 19:14
  • @PierreLafortune [See also here](http://stackoverflow.com/questions/17751862/create-a-variable-length-alist) for a bit more detail on what `substitute()` is doing in the incantation above. – Josh O'Brien Oct 07 '15 at 19:14
  • 2
    Or you can assign it to `vals <- c(substitute(), 2,2,3)` and then run the function with `do.call('[', c(list(a1), vals))`. – Pierre L Oct 07 '15 at 19:19
  • 1
    By the way OP you're welcome. Your question was about to be put on hold. Next time a good explanation can speed up the help process. : ) – Pierre L Oct 07 '15 at 19:20