7
$\begingroup$

I have a list which contains non-integers (three in this case) each of which I need to replace with a different Random Variate.

{27, 43.91405202, 56, 37, 31, 40, 50, 40.56562816, 39, 36, 27, 32, 40, 31, 18, 23, 26, 54.59260675, 21, 51}

Before I use ReplacePart I need the position of the offending elements. This line

Position[data, _?(! IntegerQ[#] &)]

produces this result of five elements, the middle three of which is my answer {{0}, {2}, {8}, {18}, {}}

I can work around that result with this

Drop[Position[data, _?(! IntegerQ[#] &), Heads -> False], -1]

My guess is that if I knew why the superfluous first and last elements were being generated I would be able to streamline my code.

Further discovery: I actually have a matrix. So my work around does not solve the problem for a list of lists

$\endgroup$
3
  • $\begingroup$ Position[data, Except[_Integer, _Real]] or Position[data, _Real] ? If this doesn't work for your matrix data, please update the question further $\endgroup$
    – Syed
    Commented Feb 21, 2022 at 18:05
  • 3
    $\begingroup$ You don't need the positions to replace the real values, e.g., list /. x_Real :> RandomVariate[dist] $\endgroup$
    – Bob Hanlon
    Commented Feb 21, 2022 at 18:21
  • $\begingroup$ @BobHanlon Agreed. But when a matrix is involved and unique rvs must be ~N[mu,sigma] with the params the same within each column but different between each column, params derived from the known values in each column (excluding the missing values which are the slots for the rvs), I have yet to figure out how to do that without knowing the positions. I probably should amend my question with an example. $\endgroup$
    – Rogo
    Commented Feb 22, 2022 at 17:16

2 Answers 2

11
$\begingroup$

By default, Position scans all levels of the expression. The position {0} denotes the head symbol List and the position {} denotes the entire expression (i.e. level zero). The fix is to restrict the search to just the first level and to exclude heads:

Position[data, _?(! IntegerQ[#] &), {1}, Heads -> False]

(* {{2}, {8}, {18}} *)

For matrices and deeper structures, adjust the level accordingly.

$\endgroup$
1
$\begingroup$
list = {27, 43.91, 56, 37, 40.5, 39, 36, "pp"};

Using SubsetPosition (new in 12.1)

SubsetPosition[list, {Except[_Integer]}]

{{2}, {5}, {8}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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