4
$\begingroup$

Suppose I have a list as follow:

l = {{"a", "b", "c"}, {"a", "b"}, {"a", "d", "b"}, {"a", "c", "e"}};

Now I am going to flatten it and apply Counts to count each element:

l // Flatten // Counts

<|"a" -> 4, "b" -> 3, "c" -> 2, "d" -> 1, "e" -> 1|>

Now I want to do followings:

  1. From the list how can I retain only sublists whose components have frequency more than 1 in the overall list l, namely the output should look like this:

    {{"a", "b", "c"}, {"a", "b"}}
    

as all "a", "b" and "c" have frequency above 1.

  1. how can I delete those sublists that contain any components that have frequency 1 from l, namely the output should look like:

    {{"a", "b", "c"}, {"a", "b"}, {"a", "b"}, {"a", "c"}}
    
$\endgroup$
3
$\begingroup$

Here's an example:

counts = l // Flatten // Counts;
mask = Map[counts[#] != 1 &, l, {2}];
Pick[l, mask]

{{"a", "b", "c"}, {"a", "b"}, {"a", "b"}, {"a", "c"}}

And for the other one,

mask = Map[counts[#] > 1 &, l, {2}];
Pick[l, And @@@ mask]

{{"a", "b", "c"}, {"a", "b"}}

Another way:

Map[
 If[counts[#] != 1, #, Nothing] &,
 l, {2}]

{{"a", "b", "c"}, {"a", "b"}, {"a", "b"}, {"a", "c"}}

If[And @@ (counts[#] > 1 & /@ #), #, Nothing] & /@ l

{{"a", "b", "c"}, {"a", "b"}}

$\endgroup$
2
$\begingroup$

Alternatives using Select rather than Pick:

l = {{"a", "b", "c"}, {"a", "b"}, {"a", "d", "b"}, {"a", "c", "e"}};
counts = Counts[Flatten@l];
  1. To obtain the sublists whose elements are repeated in the list:

    Select[ContainsNone[Keys@Select[# == 1 &]@counts]@l
    (* Out: {{"a", "b", "c"}, {"a", "b"}} *)
    
  2. To remove those sublists that contain non-repeated elements in the overall list:

    DeleteCases[Alternatives @@ Keys@Select[# == 1 &]@counts] /@ l
    (* Out: {{"a", "b", "c"}, {"a", "b"}, {"a", "b"}, {"a", "c"}} *)
    
$\endgroup$

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.