5
$\begingroup$

If I have a matrix or table of data,

Data = {{1, 2, 3}, {3, 4, 5}, {5, 6, 7}, {7, 8, 9}, {9, 10, 11}, {11, 12, 
  13}, {13, 14, 15}, {15, 16, 17}, {17, 18, 19}, {19, 20, 21}, {21, 
  22, 23}, {23, 24, 25}, {25, 26, 27}, {27, 28, 29}, {29, 30, 
  31}, {31, 32, 33}}

Is there a method of deleting or dropping a row if any column has the value defined by a list, e.g.

TestList = {1, 8 , 16, 24}

such that if any element contains one of those values then the row itself is removed?

It's achievable by using nested Select statements where you would have a Select for each column and test them individually against the list, using MemberQ but that seems a little crude.

$\endgroup$
  • 2
    $\begingroup$ Something like Select[Data, Intersection[TestList, #] === {} &]? $\endgroup$ – J. M. will be back soon Nov 19 at 14:09
  • $\begingroup$ Can this also work for the opposite case? So Select all columns which do not contain any of the test list values? $\endgroup$ – Q.P. Nov 19 at 14:12
  • $\begingroup$ You might be interested in using Transpose[] for that. $\endgroup$ – J. M. will be back soon Nov 19 at 14:14
  • $\begingroup$ Thanks, I'll have a play, your first suggestion works great! $\endgroup$ – Q.P. Nov 19 at 14:16
  • 2
    $\begingroup$ Also take a look at ContainsNone and similar functions: They are really only syntactic sugar, but they make for very readable code. For instance, your row-wise requirement could be written as Select[Data, ContainsNone[TestList]]. $\endgroup$ – MarcoB Nov 19 at 14:30
7
$\begingroup$

Let's create some play data:

SeedRandom[1234]
data = RandomInteger[{1, 20}, {10, 5}]

testlist = {2, 15, 19};

(*
{{ 2,  2,  1, 17, 18}, 
 { 5,  6, 20, 16, 17},
 {20,  3, 13,  6, 17},
 {19,  8, 15, 17,  7},
 { 2, 16,  8,  9, 14},
 {14,  2, 16,  9,  5},
 { 3, 17,  5, 17,  2},
 {14, 18, 10, 12,  7},
 {15, 19, 12,  3,  5},
 {17, 16, 12, 10, 15}}
*)

Your first task, as stated in the question, can be accomplished with:

Select[data, ContainsNone[testlist]]

(* {{ 5,  6, 20, 16, 17},
    {20,  3, 13,  6, 17},
    {14, 18, 10, 12,  7}} *)

The second task you outlined in comments, wanting to apply the filter only on certain columns (say, for instance, the first, third, and fourth), could be done with:

Select[data, ContainsNone[#[[{1, 3, 4}]], testlist] &]

(* 
{{ 5,  6, 20, 16, 17}, 
 {20,  3, 13,  6, 17},
 {14,  2, 16,  9,  5},
 { 3, 17,  5, 17,  2}, 
 {14, 18, 10, 12,  7},
 {17, 16, 12, 10, 15}} *)
$\endgroup$
  • $\begingroup$ Really awesome answer, short and simple! $\endgroup$ – Q.P. Nov 19 at 16:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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