Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to repeatedly call a module by using a Table statement. When I use an i iterator in the Table command calling the module, I receive the error message "Table::itraw: Raw object 1 cannot be used as an iterator. >>" The module also contains a separate Table statement with the i iterator.

I noticed that when I change the iterator in the Table statement calling the module to something else, say v I no longer get the error message above. This makes me think the i iterator is leaking into the module, so ....

Question 1: Am I correct that the value of the i iterator from the Table statement calling the Module is leaking into the module?

Question 2: Is this expected behavior?

Question 3: Why does this happen?

Question 4: Is there another way to solve this problem, other than to avoid the use of i as an iterator in both the Table calling the module and the module itself?

Thank you for any advice! Todd


Here is a snippet of the offending code:

errorcorrection[signaltype_,chipid_,probesetpostocheck_]:=Module[{clusters,positions,loopindex,groupminuscurrent,similarprobesets},

loopindex=1; (* initialize while loop index to 1; this loop continues for the length of the number of probesets that need checked for unusual signal - which is the length of the probesetpostocheck *)

While[loopindex<=2(*Length[probesetpostocheck[chipid]]*),

clusters=Flatten[Drop[Sort[FindClusters[signaltype[chipid][[probesetpostocheck[chipid][[loopindex]]]],3,DistanceFunction->EuclideanDistance,Method->"Agglomerate"]],-1]]; (* locate probe signals within the current probeset being evaluated that are unreliable and need replaced *)

Print[clusters];

With[{i=i},positions=Flatten[Table[Position[signaltype[chipid][[probesetpostocheck[chipid][[loopindex]]]],clusters[[i]]],{i,1,Length[clusters]}]]]

Print[positions];

If[MemberQ[controlchips,chipid],

(groupminuscurrent=DeleteCases[controlchips,x_/;x==chipid];
similarprobesets=Table[signaltype[groupminuscurrent[[i]]][[probesetpostocheck[chipid][[loopindex]]]],{i,1,Length[groupminuscurrent]}]),

(groupminuscurrent=DeleteCases[experimentchips,x_/;x==chipid];
similarprobesets=Table[signaltype[groupminuscurrent[[i]]][[probesetpostocheck[chipid][[loopindex]]]],{i,1,Length[groupminuscurrent]}])]

Print[similarprobesets];

loopindex++]]

run2 = Table[
  errorcorrection[pmsignal, experimentchips[[i]], pmpostocheck], {i, 
   1, 1}]


{11719.,1567.,2149.,2001.,1781.,1693.}

Table::itraw: Raw object 1 cannot be used as an iterator. >>

Table[Position[pmsignal[GSM356796][[pmpostocheck[GSM356796][[loopindex$112290]]]],clusters$112290[[1]]],{1,1,Length[clusters$112290]}]

run3 = Table[
  errorcorrection[pmsignal, experimentchips[[v]], pmpostocheck], {v, 
   1, 1}]

{11719.,1567.,2149.,2001.,1781.,1693.}

{7,6,8,9,17,20}

After considering everyone's responses below, I have been able to get my code to work better by replacing the With[{i=i},positions=Flatten .... statement inside the errorcorrection module with Module[{i=i},positions=Flatten .... As noted Block also works fine.

I am still puzzled, however, why i takes on a value of 1 inside the errorcorrection module, when the module is called by this statement:

run2 = Table[errorcorrection[pmsignal, experimentchips[[i]], pmpostocheck], {i, 1, 1}]

An example of output showing the iterator i is here:

run2 = Table[errorcorrection14[pmsignal, experimentchips[[i]], pmpostocheck], {i, 1, 1}]


{11719.,1567.,2149.,2001.,1781.,1693.}

i equals 1

{7,6,8,9,17,20}

Question 5: (continuing from numbering above): Doesn't the Table command in run2=Table[errorcorrection14[pmsignal, experimentchips[[i]], pmpostocheck], {i, 1, 1}] localize the iterator?

Question 6: If so, why does that value show up in the errorcorrection module?

Question 7: If i did NOT take on the value of 1 (or any value) in the errorcorrection module, would my original With[{i=i},positions=Flatten statement have worked ok?

It seems to me (in my naivety) that the problem with using With in this case, is that i is taking on a value in the module from the Table statement calling the module .... but I thought Table should localize i and prevent its value from going into the module??

Thank you again, as I struggle to understand at a "deeper" level.

share|improve this question
    
Not relevant for the question, but I think it's worth mentioning that Table is a function, not a statement. A statement is a "phrase" that tells the computer to do something. A function is something that returns a value. –  Szabolcs Apr 18 '12 at 7:58
    
@Todd I've expanded my answer to address your additional questions. Let me know if you suits your needs. –  rcollyer Apr 18 '12 at 17:35
    
@rcollyer Thank you for your time and excellent commentary. Over the past few days I have been pouring over the documentation, and I was beginning to think along the lines that you communicated in your answer. I appreciate your time investment! I owe you a beer. This goes to show that a biologist can learn a little Mathematica. –  Todd Allen Apr 18 '12 at 21:26
    
As a "newish" user, have you seen that we have a syntax highlighter script available? It makes it a lot easier to read. Also, if your in the Northeastern US, I may actually be able to take you up on that offer. –  rcollyer Apr 19 '12 at 1:18

1 Answer 1

up vote 8 down vote accepted

I know the reason for the second giving you the error: i has been set to 1. Under normal operations, this will not happen as Table has the Attribute HoldAll, so even if i has a value, Table should be shielded from it. For example,

i = 5
Table[ i, {i , 3}]
(* Out[1] = 5 
   Out[2] = {1, 2, 3}
*)

However, in the large block of code, you use this construct:

With[{i = i}, Table[ ..., {i, ...} ]

So, it is likely that the second Table is executed in a similar manner, and that is where the problem lies. For instance,

With[{i = 1}, Table[i, {i, 5}]]
(* Table::itraw: Raw object 1 cannot be used as an iterator. >>
   Out[3] = Table[1, {1, 5}]
*)

With operates by replacing i in Table with its value prior to Table doing anything which circumvents the HoldAll. Neither, Block nor Module have the same effect, so I would advise using them, instead, for this type of thing.


In your code for run2, you effectively have this code

Table[ With[{i2 = i1}, Table[ ..., {i2, ...}]], {i1, ...}]
(* I have renamed the variables for clarity, but the results are the
   same with them all set to i*)

Here, i1 is localized to the outer Table and the With sets i2 to the value of i1 which causes the error you're seeing. The reason this shows up inside errorcorrection is that i1 is not localized to errorcorrection, but takes on the global (to it) value.

Incidentally, this reveals that Table is using Block or Internal`InheritedBlock to perform its scoping. Consider,

f[x_] := {x, i}
Block[{i = 3}, f[q]]
Internal`InheritedBlock[{i = 3}, f[q]]
Module[{i = 3}, f[q]]
With[{i = 3}, f[q]]
(*
Out[131]= {q, 3}
Out[132]= {q, 3}
Out[133]= {q, i}
Out[134]= {q, i}
*)

which reveals one of the key differences between the different scoping constructs. Here i in f is interpreted as Global`i, but Module and With effectively use Unique[i], instead. So, they return Global`i unevaluated. (With actually performs a rewriting operation, but the effect is the same.) Block and Internal`InheritedBlock effectively define Unique[]`i and without any context qualifier on i in f, it is subsumed into the new context. The difference between them is that Block assumes that no definitions of i exists. But, Internal`InheritedBlock pulls in the global definitions into Unique[]` allowing for small changes to be made easily.

In the code, if i was not specified in the outer Table (as in the code for run3), then yes With would work as expected. But, the moral of the story is that Table need not be wrapped in any of scoping constructs as it does the scoping itself.

share|improve this answer
    
Yes, I was just about to type exactly that. The purpose of With is to define local constants, which is exactly not what is wanted here. –  Mark McClure Apr 16 '12 at 3:34
    
I tend to use With to define local variables, is that bad practice? If so what are the consequences? –  image_doctor Apr 16 '12 at 9:23
    
@image_doctor In the case of Table and other functions that take a Symbol, they're usually already localized via HoldAll. But, as a general method, I like to use With to define local variables, too. You just have to watch out how the variables will be used, like in the case of Table, above. –  rcollyer Apr 16 '12 at 13:36
1  
@image_doctor I think an important point is that With does not define local variables. Try With[{i = 3}, i = 5] to see what I mean (and compare to the same thing with Block or Module). It defines local constants; see mathematica.stackexchange.com/a/561/16 –  acl Apr 16 '12 at 17:53
    
@acl Yes I see your point :) I tend to use With blocks to compute once those things which I might need multiple times in a local context, often in conjunction with Map or something similar. So conceptually thought of them as variables, though in practice they aren't assigned to outside of the construction {}. Hence I didn't trip over their immutability. –  image_doctor Apr 16 '12 at 20:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.