2

I have a list called cant with some amounts of samples to take from the list community as follows:

cant = {5, 1, 2, 3, 4};
community = {{1, 2, 3, 4, 5, 6}, {1, 2, 3}, {1, 2, 3, 4}, {1, 2, 3}, {1, 2, 3, 4, 5, 6}}; 

I'm trying to find a better way to do this task:

where = {};
Table[AppendTo[where, 
 Table[Flatten[{RandomSample[community[[i]], 1], i}], {cant[[
    i]]}]];, {i, Length[community]}];

The result is:

where 
{{{3, 1}, {2, 1}, {3, 1}, {4, 1}, {4, 1}}, {{1, 2}}, {{3, 3}, {3, 3}}, {{1, 4}, {3, 4}, {1, 4}}, {{4, 5}, {1, 5}, {3, 5}, {1, 5}}}

Because with

where[[1]]
{{3, 1}, {2, 1}, {3, 1}, {4, 1}, {4, 1}}

The 5 samples in the first item (3, 2, 3, 4, and 4) have the index of community 1. I read about Reap and Sow, but really I couldn't understand how to implement this. Any idea of how to make this faster because I'm working with large communities and sampling thousands?

I appreciate your help,

Jotasmall
  • 131
  • 6

3 Answers3

5
MapThread[Thread[List[RandomChoice[#1, #2], #3]] &, {community, cant, Range@Length@cant}]

(* {{{2, 1}, {1, 1}, {3, 1}, {4, 1}, {6, 1}}, {{3, 2}}, {{4, 3}, {1, 
   3}}, {{2, 4}, {3, 4}, {1, 4}}, {{2, 5}, {3, 5}, {1, 5}, {6, 5}}} *)

Some variations:

MapIndexed[Thread[List[#1, First@#2]] &, MapThread[RandomChoice[#1, #2] &, {community, cant}]]
MapIndexed[Function[i, Join[{i}, #2]] /@ #1 &, MapThread[RandomChoice[#1, #2] &, {community, cant}]]
seismatica
  • 5,101
  • 1
  • 22
  • 33
  • I believe RandomSample should be RandomChoice. – C. E. Aug 07 '14 at 22:07
  • I agree, though it depends on OP's goal (if there should be any repeated values in the sample). Also @Mr.Wizard I finally know what you were talking about here, about nesting pure functions. – seismatica Aug 07 '14 at 22:11
  • 2
    I think the OP's code is unambiguous in this regard. It should be RandomChoice (though he correctly uses RandomSample in his code, in a different way). – C. E. Aug 07 '14 at 22:13
  • Ah now I see your point. Evaluating Table[RandomSample[community[[1]],1],{4}] several times helped me see what's going on. I fixed my answer based on your recommendation. Thanks so much! – seismatica Aug 07 '14 at 22:17
  • I created a function with the first line you gave me and works better than my initial idea, thanks! – Jotasmall Aug 08 '14 at 14:33
2
{(community[[#]]~RandomSample~1)[[1]], #} & /@ 
   ConstantArray[#, cant[[#]]] & /@ Range[Length@cant]
Basheer Algohi
  • 19,917
  • 1
  • 31
  • 78
2
Thread[{RandomSample[community[[#]], cant[[#]]], #}] & /@ Range[Length[community]]
(* {{{2, 1}, {3, 1}, {5, 1}, {1, 1}, {4, 1}}, 
    {{3, 2}},
    {{2, 3}, {4, 3}},
    {{3, 4}, {2, 4}, {1, 4}},
    {{3, 5}, {5, 5}, {4, 5}, {1, 5}}} *)
kglr
  • 394,356
  • 18
  • 477
  • 896