Lets say I have 101 instances of data with multiple attributes. In particular case, one attribute has 7 unique values. I want to get 7<=n<=101 element positions from data, in a way that it contains at least 1 of each unique attribute case.
First I get the example data and gather it by particular attribute:
data = Import["https://raw.github.com/BioGeek/aima/master/aima-data-read-only/zoo.csv"];
g = GatherBy[data, #[[18]] &];
List g of lists with element sizes h
h = Length[#] & /@ g (*{41,13,20,10,8,4,5}*)
Following works in the best case scenario
n = RandomInteger[{Length[g], Length[data]}]
l = RandomSample[RandomSample[#] & /@ IntegerPartitions[n, {Length[g]}], 1][[1]]
s = Table[RandomSample[g[[i]], l[[i]]], {i, 1, Length[g]}]
p = Sort[Position[data, #][[1]][[1]] & /@ #] & /@ s
Example result:
{{30,33},{8,62},{57,72,96,101},{14,73,78,82,86},{25,40,43,89},{26,27,53,90},{77,81,91,92}}
I can bruteforce, but I do not like the idea.
While[MemberQ[Table[h[[i]] >= l[[i]], {i, 1, Length[h]}], False],
l = RandomSample[RandomSample[#] & /@ IntegerPartitions[n, {Length[g]}], 1][[1]]]
How do I find random sample l so it is less then gap sizes h?
edit:
If n = 7

If n = 21

Problem is that h = {41,13,20,10,8,4,5} and even if n = 11 then l = {1,1,1,1,1,5,1} that is invalid as there are not enough elements in that sublist.
edit 2
f[data_List, n_Integer] := Module[{data1 = data, h, k},
k = RandomSample[DeleteCases[data1, Alternatives @@
(h = RandomChoice /@ GatherBy[data1, #[[18]] &])], n - 7];
h~Union~k]