Split ranked distribution by approximately equal shares of total

时间:2018-02-03 07:45:16

标签: r dataframe split grouping

I have a sample ranked distribution. I want to split the distribution by approximately equal shares of the total (i.e. sums of value). Is there a more efficient method than mine or an R function to do this?

Example with a split into quarters. This could be adjusted for a split into thirds, fifths, etc. I'm looking for a generic method where the specific split is a parameter. (I assume that there are no duplicate values as there is no other criteria for ranking duplicate values.)

set.seed(123)
df <- data.frame(var=sample(seq(from=1, to=100), size=50, replace=F))
df <- df[order(-df$var), 1, drop = FALSE]
df$cumshare <- cumsum(df$var)/sum(df$var)*100
df$split <- with(df, cut(cumshare, 
                     breaks=c(-Inf, 
                              cumshare[abs(cumshare-25)==min(abs(cumshare-25))], 
                              cumshare[abs(cumshare-50)==min(abs(cumshare-50))], 
                              cumshare[abs(cumshare-75)==min(abs(cumshare-75))], 
                              Inf), labels=4:1, right=T))

Actual data:

c(55742.1666666667, 290442.722222222, 49324.4444444444, 33579.6111111111, 
328733.055555556, 287541.222222222, 49200.2777777778, 294698.111111111, 
50753.4444444444, 89410.7777777778, 28995.1111111111, 145511.111111111, 
146454, 38917.7777777778, 107209.055555556, 148396.444444444, 
55987.6111111111, 2111160.33333333, 120093.277777778, 36380.3333333333, 
178954.777777778, 616605.333333333, 172910.277777778, 1079663.11111111, 
57802.8333333333, 72345.8888888889, 303153.555555556, 54359.6944444444, 
32260.8333333333, 131608.5, 36684.5555555556, 66237.2777777778, 
51570.6666666667, 66111.75, 88323.8333333333, 453165.777777778, 
49726.1111111111, 49557.9444444444, 83656.6666666667, 51943.1666666667, 
35903.5, 214596.666666667, 2302904.88888889, 141095.222222222, 
53161.1666666667, 54681.7222222222, 431179.722222222, 94553.6666666667, 
33722.4444444444, 469659.666666667, 54570.3333333333, 97399.3888888889, 
26675.6111111111, 154970.055555556, 172014.166666667, 40395.6666666667, 
40127.0555555556, 23224.4444444444, 31740.4444444444, 120782.833333333, 
46069.1666666667, 76339.8888888889, 99523.25, 232789.444444444, 
895023.388888889, 75775.3888888889, 210166.111111111, 30132.3333333333, 
4047277.94444444, 56065.6666666667, 907285.611111111, 63667.6111111111, 
39144.7777777778, 955029.5, 42049.7222222222, 57606, 219019.111111111, 
66462.2222222222, 275374.888888889, 98144.5555555556, 40176.5555555556, 
796597.666666667, 141582.222222222, 26581.5, 74066.7222222222, 
30879.7777777778, 2598390.38888889, 61316.3333333333, 26347.3333333333, 
50453.5555555556, 160598.944444444, 334948.722222222, 49111.5, 
48745.7777777778, 148978.5, 1079429.16666667, 278756.5, 1764416.22222222, 
53241.5, 47752.5555555556, 50508.1111111111, 104714.833333333, 
225147.833333333, 44248.7222222222, 66727.5555555556, 29330.1111111111, 
38886.7222222222, 113694.944444444, 33404.3333333333, 206358.777777778, 
116861.388888889, 118912.722222222, 145794.222222222, 25698.7777777778, 
102560.5, 37417, 95687.7222222222, 173247.055555556, 43501.1666666667, 
130110.944444444, 74804.2222222222, 46389.7777777778, 42087.2222222222, 
103575, 100102.777777778, 190218.777777778, 232576.055555556, 
31257.3888888889, 84825.2222222222, 60395.5, 28503.5, 42272.0555555556, 
36263.8888888889, 39512.3888888889, 33953.4444444444, 47905.6111111111, 
446287.944444444, 19784.8888888889, 28844.4444444444, 64629.1111111111, 
147138.611111111, 321922.222222222, 55509.5, 325558.333333333, 
126607.944444444, 80069.2222222222, 30684.6111111111, 22001.1111111111, 
264475.333333333, 50357.1111111111, 548571.305555556, 47638.2777777778, 
141388.166666667, 55071.2777777778, 11135.0555555556, 25859.6666666667, 
32019.1111111111, 73675.1666666667, 2163583.38888889, 111229.611111111, 
158437.222222222, 46390.7777777778, 816072.111111111, 61759.5555555556, 
45123, 50086.2777777778, 213269.388888889, 56551, 504643.722222222, 
31948.6111111111, 57210, 51631.2222222222, 64497.6666666667, 
49734.5, 40510.7222222222, 70703.3888888889, 58998.3333333333, 
123946.555555556, 40205.6666666667, 885198.388888889, 71431.4444444444, 
92844.7777777778, 107837.388888889, 46643.6111111111, 311787.055555556, 
36217.8888888889, 62148.9444444444, 175317.111111111, 68446.5, 
72083.5555555556, 40576.3333333333, 166788.611111111, 214811.888888889, 
163634.333333333, 62655.3888888889, 44876.9444444444, 735689.833333333, 
37319.6666666667, 31621.3888888889, 42173.8888888889, 20823.9444444444, 
44638.5555555556, 207579.055555556, 48769.8333333333, 133521.277777778, 
280017.888888889, 37689.4444444444, 78155.3888888889, 31336.9444444444, 
5192167.38888889, 528808.222222222, 102686.666666667, 94212.9444444444, 
85213.4444444444, 24507.6111111111, 285528.611111111, 177986.222222222, 
27596.3333333333, 44802.3333333333, 47881.0555555556, 149679.944444444, 
65873.0555555556, 535497.388888889, 41023.6666666667, 1948796.11111111, 
36360, 34899.8333333333, 60902.5555555556, 769937, 1659862.16666667, 
45497.3333333333, 153351.944444444, 128934.555555556, 67756.4444444444, 
37699.3333333333, 131335.111111111, 41817.7777777778, 39603.7222222222, 
37455.2777777778, 42339.1111111111, 53137.5, 115317.388888889, 
55305.7777777778, 103718.055555556, 705847.222222222, 31484.8333333333, 
334858.222222222, 495883.111111111, 7750164.72222222, 56271.5555555556, 
222468.055555556, 106672.111111111, 76888, 25530.2222222222, 
48980.2777777778, 158238.777777778, 458924.166666667, 60855.3888888889, 
391351.888888889, 876153.166666667, 83262.2777777778, 44640.9444444444, 
249583.888888889, 168560.833333333, 58951.5, 35399.5, 124880.777777778, 
163233.166666667, 2507562.83333333, 1489490.83333333, 27220.2777777778, 
1056903.55555556, 55849.3333333333, 24990.8888888889, 220106.555555556, 
888052.666666667, 100748.722222222, 52622.5, 616616.583333333, 
154470.611111111, 46230.9444444444, 35109.7222222222, 70426.2777777778, 
410393.666666667, 49972.1666666667, 147646.833333333, 48452.1666666667, 
176712.722222222, 497727.166666667, 987208.055555556, 138152.166666667, 
95909.8888888889, 437641, 137330.111111111, 53687.7222222222, 
35542.5555555556, 655479.611111111, 82172.6111111111, 88705.3888888889, 
35860.8888888889, 45937.3888888889, 1217632.5, 108375.055555556, 
104541.944444444, 116954.055555556, 507878.666666667, 36932.7222222222, 
700132.166666667, 1130749.55555556, 1906493, 924910.5, 82808.2777777778, 
74197.1666666667, 46157.6666666667, 139371.888888889, 158905.388888889, 
127244.833333333, 230246.444444444, 1473276.27777778, 39639, 
22067.5, 53811.7222222222, 38325.1666666667, 158710.388888889, 
26448.3888888889, 76945.3888888889, 118379.388888889, 126642.666666667, 
124153.666666667, 182053, 84095.0555555556, 224624.444444444, 
168207.777777778, 44703, 44461.9444444444, 39357.5555555556, 
165221.222222222, 32205.7777777778, 261875.444444444, 107056.277777778, 
1002739.83333333, 60318.6111111111, 45877.3888888889, 12402.3888888889, 
272289.777777778, 87007.0555555556, 181073.888888889, 304337.888888889, 
379288.5, 76657.0555555556, 82150.1666666667, 337041.277777778, 
100925.444444444, 42132.3611111111, 101530.888888889, 31885.5, 
46163.1666666667, 597666.388888889, 85602.2777777778, 93943.1111111111, 
19012, 40618.2777777778, 2363693, 74217.5, 28535.2222222222, 
63010.3888888889, 40776.0555555556, 30998.4444444444, 54670.1666666667, 
260350.666666667, 49170.7222222222, 46471.6666666667, 89778.1111111111, 
47711.6666666667, 231108.5, 315693.055555556, 61724, 157740.222222222, 
210989.388888889, 28840.5555555556, 38573.3888888889)

1 个答案:

答案 0 :(得分:1)

I believe this does what you want. Note that while you mention ranked data, this solution also works with unordered data, however, the largest values will not be put together in one group in that case.

library(Hmisc)
no_groups = 4    
split(df$var,cut2(cumsum(df$var),seq(no_groups)/no_groups*sum(df$var)))

Output:

$`[  98, 660)`
[1] 98 97 94 91 90 89 88

$`[ 660,1320)`
[1] 87 86 85 84 83 81 79 78

$`[1320,1980)`
[1] 77 75 73 72 69 68 63 60 59

$`[1980,2640]`
 [1] 55 54 51 50 49 47 44 42 41 32 29 27 25 24 22 21 20 15 14 13 11  9  8  5  4  2

Or alternatively, if you want a column that indicates the group number:

library(Hmisc)
no_groups = 4    
df$group = as.numeric(cut2(cumsum(df$var),seq(no_groups)/no_groups*sum(df$var)))

We can easily check the group totals:

df %>% group_by(group) %>% summarize(sum(var))

# A tibble: 4 x 2
  group `sum(var)`
  <dbl>      <int>
1     1        647
2     2        663
3     3        616
4     4        714

Hope this helps!


On your actual data:

df <- data.frame(var=c(55742.1666666667, 290442.722222222, 49324.4444444444, 33579.6111111111, 
                       328733.055555556, 287541.222222222, 49200.2777777778, 294698.111111111, 
                       50753.4444444444, 89410.7777777778, 28995.1111111111, 145511.111111111, 
                       146454, 38917.7777777778, 107209.055555556, 148396.444444444, 
                       55987.6111111111, 2111160.33333333, 120093.277777778, 36380.3333333333, 
                       178954.777777778, 616605.333333333, 172910.277777778, 1079663.11111111, 
                       57802.8333333333, 72345.8888888889, 303153.555555556, 54359.6944444444, 
                       32260.8333333333, 131608.5, 36684.5555555556, 66237.2777777778, 
                       51570.6666666667, 66111.75, 88323.8333333333, 453165.777777778, 
                       49726.1111111111, 49557.9444444444, 83656.6666666667, 51943.1666666667, 
                       35903.5, 214596.666666667, 2302904.88888889, 141095.222222222, 
                       53161.1666666667, 54681.7222222222, 431179.722222222, 94553.6666666667, 
                       33722.4444444444, 469659.666666667, 54570.3333333333, 97399.3888888889, 
                       26675.6111111111, 154970.055555556, 172014.166666667, 40395.6666666667, 
                       40127.0555555556, 23224.4444444444, 31740.4444444444, 120782.833333333, 
                       46069.1666666667, 76339.8888888889, 99523.25, 232789.444444444, 
                       895023.388888889, 75775.3888888889, 210166.111111111, 30132.3333333333, 
                       4047277.94444444, 56065.6666666667, 907285.611111111, 63667.6111111111, 
                       39144.7777777778, 955029.5, 42049.7222222222, 57606, 219019.111111111, 
                       66462.2222222222, 275374.888888889, 98144.5555555556, 40176.5555555556, 
                       796597.666666667, 141582.222222222, 26581.5, 74066.7222222222, 
                       30879.7777777778, 2598390.38888889, 61316.3333333333, 26347.3333333333, 
                       50453.5555555556, 160598.944444444, 334948.722222222, 49111.5, 
                       48745.7777777778, 148978.5, 1079429.16666667, 278756.5, 1764416.22222222, 
                       53241.5, 47752.5555555556, 50508.1111111111, 104714.833333333, 
                       225147.833333333, 44248.7222222222, 66727.5555555556, 29330.1111111111, 
                       38886.7222222222, 113694.944444444, 33404.3333333333, 206358.777777778, 
                       116861.388888889, 118912.722222222, 145794.222222222, 25698.7777777778, 
                       102560.5, 37417, 95687.7222222222, 173247.055555556, 43501.1666666667, 
                       130110.944444444, 74804.2222222222, 46389.7777777778, 42087.2222222222, 
                       103575, 100102.777777778, 190218.777777778, 232576.055555556, 
                       31257.3888888889, 84825.2222222222, 60395.5, 28503.5, 42272.0555555556, 
                       36263.8888888889, 39512.3888888889, 33953.4444444444, 47905.6111111111, 
                       446287.944444444, 19784.8888888889, 28844.4444444444, 64629.1111111111, 
                       147138.611111111, 321922.222222222, 55509.5, 325558.333333333, 
                       126607.944444444, 80069.2222222222, 30684.6111111111, 22001.1111111111, 
                       264475.333333333, 50357.1111111111, 548571.305555556, 47638.2777777778, 
                       141388.166666667, 55071.2777777778, 11135.0555555556, 25859.6666666667, 
                       32019.1111111111, 73675.1666666667, 2163583.38888889, 111229.611111111, 
                       158437.222222222, 46390.7777777778, 816072.111111111, 61759.5555555556, 
                       45123, 50086.2777777778, 213269.388888889, 56551, 504643.722222222, 
                       31948.6111111111, 57210, 51631.2222222222, 64497.6666666667, 
                       49734.5, 40510.7222222222, 70703.3888888889, 58998.3333333333, 
                       123946.555555556, 40205.6666666667, 885198.388888889, 71431.4444444444, 
                       92844.7777777778, 107837.388888889, 46643.6111111111, 311787.055555556, 
                       36217.8888888889, 62148.9444444444, 175317.111111111, 68446.5, 
                       72083.5555555556, 40576.3333333333, 166788.611111111, 214811.888888889, 
                       163634.333333333, 62655.3888888889, 44876.9444444444, 735689.833333333, 
                       37319.6666666667, 31621.3888888889, 42173.8888888889, 20823.9444444444, 
                       44638.5555555556, 207579.055555556, 48769.8333333333, 133521.277777778, 
                       280017.888888889, 37689.4444444444, 78155.3888888889, 31336.9444444444, 
                       5192167.38888889, 528808.222222222, 102686.666666667, 94212.9444444444, 
                       85213.4444444444, 24507.6111111111, 285528.611111111, 177986.222222222, 
                       27596.3333333333, 44802.3333333333, 47881.0555555556, 149679.944444444, 
                       65873.0555555556, 535497.388888889, 41023.6666666667, 1948796.11111111, 
                       36360, 34899.8333333333, 60902.5555555556, 769937, 1659862.16666667, 
                       45497.3333333333, 153351.944444444, 128934.555555556, 67756.4444444444, 
                       37699.3333333333, 131335.111111111, 41817.7777777778, 39603.7222222222, 
                       37455.2777777778, 42339.1111111111, 53137.5, 115317.388888889, 
                       55305.7777777778, 103718.055555556, 705847.222222222, 31484.8333333333, 
                       334858.222222222, 495883.111111111, 7750164.72222222, 56271.5555555556, 
                       222468.055555556, 106672.111111111, 76888, 25530.2222222222, 
                       48980.2777777778, 158238.777777778, 458924.166666667, 60855.3888888889, 
                       391351.888888889, 876153.166666667, 83262.2777777778, 44640.9444444444, 
                       249583.888888889, 168560.833333333, 58951.5, 35399.5, 124880.777777778, 
                       163233.166666667, 2507562.83333333, 1489490.83333333, 27220.2777777778, 
                       1056903.55555556, 55849.3333333333, 24990.8888888889, 220106.555555556, 
                       888052.666666667, 100748.722222222, 52622.5, 616616.583333333, 
                       154470.611111111, 46230.9444444444, 35109.7222222222, 70426.2777777778, 
                       410393.666666667, 49972.1666666667, 147646.833333333, 48452.1666666667, 
                       176712.722222222, 497727.166666667, 987208.055555556, 138152.166666667, 
                       95909.8888888889, 437641, 137330.111111111, 53687.7222222222, 
                       35542.5555555556, 655479.611111111, 82172.6111111111, 88705.3888888889, 
                       35860.8888888889, 45937.3888888889, 1217632.5, 108375.055555556, 
                       104541.944444444, 116954.055555556, 507878.666666667, 36932.7222222222, 
                       700132.166666667, 1130749.55555556, 1906493, 924910.5, 82808.2777777778, 
                       74197.1666666667, 46157.6666666667, 139371.888888889, 158905.388888889, 
                       127244.833333333, 230246.444444444, 1473276.27777778, 39639, 
                       22067.5, 53811.7222222222, 38325.1666666667, 158710.388888889, 
                       26448.3888888889, 76945.3888888889, 118379.388888889, 126642.666666667, 
                       124153.666666667, 182053, 84095.0555555556, 224624.444444444, 
                       168207.777777778, 44703, 44461.9444444444, 39357.5555555556, 
                       165221.222222222, 32205.7777777778, 261875.444444444, 107056.277777778, 
                       1002739.83333333, 60318.6111111111, 45877.3888888889, 12402.3888888889, 
                       272289.777777778, 87007.0555555556, 181073.888888889, 304337.888888889, 
                       379288.5, 76657.0555555556, 82150.1666666667, 337041.277777778, 
                       100925.444444444, 42132.3611111111, 101530.888888889, 31885.5, 
                       46163.1666666667, 597666.388888889, 85602.2777777778, 93943.1111111111, 
                       19012, 40618.2777777778, 2363693, 74217.5, 28535.2222222222, 
                       63010.3888888889, 40776.0555555556, 30998.4444444444, 54670.1666666667, 
                       260350.666666667, 49170.7222222222, 46471.6666666667, 89778.1111111111, 
                       47711.6666666667, 231108.5, 315693.055555556, 61724, 157740.222222222, 
                       210989.388888889, 28840.5555555556, 38573.3888888889))

library(Hmisc)
no_groups = 4    
df$group = as.numeric(cut2(cumsum(df$var),seq(no_groups)/no_groups*sum(df$var)))
df %>% group_by(group) %>% summarize(sum(var))

Output:

# A tibble: 4 x 2
  group `sum(var)`
  <dbl>      <dbl>
1     1   25097871
2     2   25179430
3     3   25051105
4     4   25509319