Combinaciones de k elementos tomados de n en n. Con SAS y con R

Me gustaría plantearos un problema que me ha ocurrido recientemente con SAS. Necesitaba todas las posibles combinaciones de 9 elementos tomados de n en n. Tenia que crear un dataset con todas estas combinaciones. Antes de ponerme a programar toca buscar en Google “sas combinations” y tras un rato buscando encuentro el siguiente link. Este link contiene una macro de SAS que nos permite crear todas las combinaciones de k elementos tomados de n en n:


%macro comb(dsout=_null_,n=,k=);
%local dsout n k start stop i;
%let start = 1;
%let stop = %eval(&n. - &k.);
data &dsout;
retain j 1;
%do i=1 %to &k;
%let stop=%eval(&stop.+1);
do varib&i = &start to &stop;
%let start=%str(%(varib&i + 1 %));
%end;
output ;
j + 1;
%do i=1 %to &k;
end;
%end;
run;
%mend comb;

Es un código bastante eficiente que, al final, es una forma de parametrizar un bucle. De todos modos roza la genialidad. Esta misma duda se planteo en la lista de R.  Y me pare a pensar: ¿Cómo puede hacer esto mismo en R? Escribimos en Google “combinations R” y la segunda entrada es:

https://stat.ethz.ch/pipermail/r-help/2002-November/026716.html El paquete gregmisc tiene la funcion combinations:


combinations(4, 2)
[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 1 4
[4,] 2 3
[5,] 2 4
[6,] 3 4

Es decir, solo tenemos que irnos al CRAN  o poner require(gregmisc). Ahora bien, ¿que sucede si lo que deseamos es crear combinaciones de un vector de valores? Por ejemplo, si tengo 9 variables para mi modelo cual es el mejor modelo posible tomando variables de 4 en 4. Os planteo como ejercicio hacer esto. A ver si os cuesta mas con R o con SAS. Es sencillo pinchad los link…

5 comentarios en “Combinaciones de k elementos tomados de n en n. Con SAS y con R

  1. Buen día, tengo un problema con macro variables,
    quiero guardar valores en variables aparte y después llamarlas, ya tengo éstas macros en donde genero todas las variables que necesito.
    /*Genera las primeras variables (3)*/
    %macro suma (tab_in);
    proc sql;
    %do i=1 %to &ncluster.;
    select sum(u&i.**&m) into : u&i._2
    from &tab_in;
    %end;
    quit;
    %mend suma;

    /*Genera las segundas variables (12)*/

    %macro crea_var_sum(tab_in);
    dat &tab_in;
    set &tab_in;
    %do j=1 %to &ncluster;
    %do i=1 %to &numvar;
    var&i._c&j. = ((u&j.**2)*var&i. ) ;
    %end;
    %end;
    run;
    %mend crea_var_sum;

    Ahora quiero utilizar éstos dos tipos de variables, para que haga nuevas variables de ésta forma:

    data &tabla_in;
    set &tabla_in;
    c11=&sum_var1_c1/&u1_2;
    c12=&sum_var2_c1/&u1_2;
    c13=&sum_var3_c1/&u1_2;
    c14=&sum_var4_c1/&u1_2;
    c21=&sum_var1_c2/&u2_2;
    run;

    /***************/
    %macro centro (tab_in);
    data &tab_in;
    set &tab_in;
    %do j=1 %to &ncluster;
    %do i=1 %to &numvar;
    %put &i=sum_var&i._c&j.;
    c&j.&i.=&&sum_var&i._c&j./&&u&j._2;
    %end;
    %end;
    run;
    %mend centro;
    /***********************/
    Lo estoy haciendo así, pero no me genera los valores, necesito ayuda, por favooooor!

  2. Hola,

    La verdad es que no te entiendo muy bien, podrías hacer algo parecido a esto:

    %let numcluster= 3 ;
    %let numvar= 12 ;
    data datos;
    do i=1 to &numcluster.;
    do j=1 to &numvar.;

    cluster = compress(put(i,best12.));
    nvar = compress(put(j,best12.));

    length palabra $50;
    palabra = ‘c’ || cluster || nvar || ‘=&sum_var’ ||
    nvar || cluster || ‘&u’ || nvar || ‘_2’;
    palabra = compress(palabra);
    output;
    end;
    end;
    run;

    proc sql noprint;
    select palabra into: frase separated by “;”
    from datos;
    quit;

    %put _user_;

    Saludos.

  3. Creo que no me explique bien, lo que necesitaba era mandar llamar a la variable que había almacenado antes. Ya lo resolví, metí a la macro tanto los valores que se crean (con :into) como la función en donde llamo esos valores y así sí funciona, de todas formas, ¡Muchas gracias!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *