2017-10-16 6 views
1

J'ai trois variables: X, Y et Z. Je veux trouver toutes les combinaisons de X, Y et Z qui s'ajoutent à 100. X, Y et Z ne peut prendre que des valeurs comprises entre [0,100]. Le ouput devrait ressembler somehtinkg comme ceci:R: obtenir toutes les combinaisons de trois nombres qui totalisent 100

X Y Z Sum 
100 0 0 100 
99 1 0 100 
99 0 1 100 
98 2 0 100 
98 1 1 100 
98 0 2 100 

et ainsi de suite ...

Toute suggestion sur la façon d'obtenir toutes les combinaisons possibles?

+0

dupes proposées: [r - combinaisons uniques de tous les éléments de deux ou plusieurs vecteurs] (https://stackoverflow.com/q/11388359/903061), [Comment générer une matrice de combinaisons?] (https://stackoverflow.com/q/3993546/903061). Générer toutes les combinaisons, utiliser 'rowSums', et sous-ensemble où la somme des lignes' == 100'. – Gregor

+0

Le meilleur moyen que je peux trouver est de fixer un nombre comme constante et la question sera beaucoup plus facile. Par exemple, lorsque x = 0, il y a 101 combinaisons de y et z. quand x = 1, il y a 100 combinaisons de y et z. Ainsi de suite. – Arthur

+0

'partitions :: composition (100, 3)'; [Génération de toutes les permutations de N balles dans M bins] (https://stackoverflow.com/questions/27064675/generating-all-permutations-of-n-balls-in-m-bins/27064925#27064925) – Henrik

Répondre

3

Puisque vous êtes limité à 1: 100 sur seulement trois colonnes, cela est facile à force brute. Aurait besoin d'une solution plus intelligente si la gamme était plus grande.

library(data.table) 

df <- expand.grid(X = 0:100, 
        Y = 0:100, 
        Z = 0:100) 

setDT(df) 

df[, Sum := X + Y + Z] 
df[Sum == 100] 
#   X Y Z Sum 
# 1: 100 0 0 100 
# 2: 99 1 0 100 
# 3: 98 2 0 100 
# 4: 97 3 0 100 
# 5: 96 4 0 100 
# ---    
# 5147: 1 1 98 100 
# 5148: 0 2 98 100 
# 5149: 1 0 99 100 
# 5150: 0 1 99 100 
# 5151: 0 0 100 100 
+0

Belle solution! Je travaillais avec 'expand.grid' toute la semaine passée mais je n'y avais pas pensé! – Arthur

+0

Ou plus simplement 'df [(X + Y + Z) == 100]' –

+1

@RichScriven Vrai, mais il faut ajouter une colonne Sum pour obtenir la sortie dans l'OP. Pourrait en faire 'df [(X + Y + Z) == 100,. (X, Y, Z, Sum = 100)]' mais je ne suis pas sûr si c'est beaucoup plus clair que les deux étapes. –

4

Une alternative (peut-être plus efficace pour un grand nombre) serait

df <- do.call(rbind, lapply(0:100, function(i) data.frame(x=i, y=0:(100-i)))) 
df$z <- 100-df$x-df$y 
+1

Il est probable que cela évolue mieux que ma solution, car vous ne générez que les lignes correctes, plutôt que toutes les combinaisons, puis les sous-ensembles. Aller beaucoup au-dessus de 0: 100 utilise une bonne quantité de RAM avec ma méthode. –