[R-es] Combinaciones sin repetición...con restricciones

Carlos Ortega cof en qualityexcellence.es
Jue Abr 28 21:05:25 CEST 2016


Hola,

Sí, no había caído en la cuenta de que sólo querías "A" y "B" y no el resto
de cadenas donde aparecieran otras letras...

Esto lo soluciona:

#----------------
library(stringr)
my_choice <- function(conjunto, cual_1, cual_2) {

  #Todas combinaciones cogidas de 1, 2, ... n (número elementos de
"conjunto")
  ele_ment <- conjunto
  all_comb <- vector()
  for (i in 1:length(ele_ment)) {
    com_tmp <- combn(ele_ment, i, FUN=str_c, simplify = TRUE, collapse="_")
    all_comb <- c(all_comb, com_tmp)
  }

  #Detección de presencia de "cual_1" y "cual_2" en el conjunto...
  cu_al <- paste(cual_1,cual_2,sep="|")
  res_out <- all_comb[str_detect(all_comb, cu_al)]
  cual_new <- c(cual_1, cual_2)
  res_def <- res_out[ !str_detect(res_out, paste(setdiff(ele_ment,
cual_new),collapse="|")) ]
  return(res_def)
}

set_examp <- c('a','b','c','d')
my_choice(set_examp, 'a', 'b')

#----------------

Aplicándole el ejemplo se obtiene:
> set_examp <- c('a','b','c','d')
> my_choice(set_examp, 'a', 'b')
[1] "a"   "b"   "a_b"

En tu código lo que veo es que incluyes la selección explícita de "a", "b"
y no "c" y no "d".
Y claro cuando amplias a otro conjunto de letras, te ves obligado a cambiar
el código.
Por eso he incluido la sentencia de "setdiff" para buscar automáticamente
las letras que no escoges  del conjunto inicial para descartar las
combinaciones en las que aparecen.

Saludos,
Carlos Ortega
www.qualityexcellence.es



El 28 de abril de 2016, 20:37, giltrapo <giltrapo en gmail.com> escribió:

> Hola, Carlos.
>
> Primero, muchas gracias por el código. No es exactamente lo que quería,
> porque la parte "Detección de presencia de "cual_1" y "cual_2"... no
> excluye aquellas combinaciones en las que está presente también el objeto
> c, pero me ha servido de base e inspiración para elaborar otro código.
>
> He copiado la primera parte de tu función, para crear todas las
> combinaciones que necesite en un momento determinado, y le he agregado un
> par de parámetros para decidir el rango del orden de las combinaciones (por
> ejemplo, todas las combinaciones de los 7 objetos, desde el orden 2 al 4).
> También he preferido guardar todas las combinaciones en un data frame,
> porque mi objetivo último sería poder asignar cada uno de los objetos que
> estoy combinando a una variable concreta. Por ejemplo, la V1 es siempre el
> Objeto 1 (a), la V2 es siempre el Objeto 2 (a,b), y así sucesivamente con
> todos los objetos. De momento no lo he logrado, pero seguiré intentándolo.
>
> my_choice <- function(conjunto, minimo, maximo) {
>         ele_ment <- conjunto
>         all_comb <- as.data.frame(matrix(data = NA, 0, maximo))
>         for (i in minimo:maximo) {
>                 com_tmp <- as.data.frame(t(combn(
>                         c("a", "b", "c", "a,b", "a,c", "b,c", "a,b,c"),i)))
>                 all_comb <- merge(all_comb, com_tmp, all.x = TRUE, all.y =
> TRUE)
>         }
>         return(all_comb)
> }
>
> Con esta función he obtenido todas las combinaciones que necesito. Por
> ejemplo, volviendo a mi ejemplo del principio, si quisiera obtener todas
> las combinaciones posibles de los 7 objetos, desde el rango 1 al 7:
>
> datos <- c("a", "b", "c", "a,b", "a,c", "b,c", "a,b,c")
>
> df <- my_choice(datos, 1, 7)
>
> Ahora ya tengo un data frame con las 127 combinaciones posibles de los 7
> objetos.
>
> El filtro del data frame lo hago con apply y grepl (lo intenté con
> str_detect, pero me daba problemas con las filas que tenían NA)
>
> Ejemplo: combinaciones que tengan los elementos a y b, pero no c
>
> df[apply(df, 1, function(x) any(grepl("a", x)) & any(grepl("b", x)) &
> all(!grepl("c", x))),]
>
>
> Ejemplo: combinaciones que tengan los elementos a, b y c
>
> df[apply(df, 1, function(x) any(grepl("a", x)) & any(grepl("b", x)) &
> any(grepl("c", x))),]
>
>
> Muchas gracias de nuevo por la ayuda, Carlos, y un fuerte saludo!
>
>
> Jose Ignacio
>
> 2016-04-27 23:34 GMT+02:00 Carlos Ortega <cof en qualityexcellence.es>:
>
>> Hola,
>>
>> Esta es una forma de hacerlo,
>>
>> #-----------------------
>> library(stringr)
>> my_choice <- function(conjunto, cual_1, cual_2) {
>>
>>   #Todas combinaciones cogidas de 1, 2, ... n (número elementos de
>> "conjunto")
>>   ele_ment <- conjunto
>>   all_comb <- vector()
>>   for (i in 1:length(ele_ment)) {
>>     com_tmp <- combn(ele_ment, i, FUN=str_c, simplify = TRUE,
>> collapse="_")
>>     all_comb <- c(all_comb, com_tmp)
>>   }
>>
>>   #Detección de presencia de "cual_1" y "cual_2" en el conjunto...
>>   cu_al <- paste(cual_1,cual_2,sep="|")
>>   res_out <- all_comb[str_detect(all_comb, cu_al)]
>>   return(res_out)
>> }
>> #-----------------------
>>
>> Ejemplo:
>>
>> > set_examp <- c('a','b','c','d')
>> > my_choice(set_examp, 'a', 'b')
>>  [1] "a"       "b"       "a_b"     "a_c"     "a_d"     "b_c"     "b_d"
>>   "a_b_c"
>>  [9] "a_b_d"   "a_c_d"   "b_c_d"   "a_b_c_d"
>>
>> La función calcula todas las combinaciones sin repetición posibles y
>> extrae los elementos donde están presentes "cual_1" y "cual_2". No está
>> preparada para que pueda funcionar con un sólo "cual", pero solucionarlo no
>> es demasiado complejo.... así no tendrás que usar Excel para esto...
>>
>> Saludos,
>> Carlos Ortega
>> www.qualityexcellence.es
>>
>>
>> El 27 de abril de 2016, 17:48, giltrapo <giltrapo en gmail.com> escribió:
>>
>>> Hola, tengo que resolver un problema para el que normalmente utilizaría
>>> excel, pero me gustaría intentar resolverlo con R. Se trata de lo
>>> siguiente:
>>>
>>> Tengo tres elementos: a, b y c.
>>>
>>> Dichos elementos están agrupados en siete objetos, producto de todas las
>>> combinaciones sin repetición posibles:
>>>
>>> Objeto 1: a
>>> Objeto 2: b
>>> Objeto 3: c
>>> Objeto 4: a y b
>>> Objeto 5: a y c
>>> Objeto 6: b y c
>>> Objeto 7: a, b y c
>>>
>>> Mi objetivo es obtener todas las combinaciones sin repetición posibles de
>>> orden n, en las que estén presentes, única y exclusivamente, los
>>> elementos
>>> que yo elija.
>>>
>>> Ejemplo 1: ¿en cuántas combinaciones sin repetición de los objetos
>>> anteriores, tomados de dos en dos, están presentes los elementos a y b
>>> (SÓLO a y b)?
>>>
>>> Solución:
>>> (Objeto 1, Objeto 2)
>>> (Objeto 1, Objeto 4)
>>> (Objeto 2, Objeto 4).
>>>
>>> Un paso más allá consistiría en obtener todas las combinaciones sin
>>> repetición posibles de cualquier orden, en las que estén presentes,
>>> única y
>>> exclusivamente, los elemento que yo elija.
>>>
>>> Ejemplo 2: ¿en cuántas combinaciones sin repetición de cualquier orden de
>>> los objetos anteriores están presentes los elementos a y b (SÓLO a y b)?
>>>
>>> Solución:
>>> (Objeto 4)
>>> (Objeto 1, Objeto 2)
>>> (Objeto 1, Objeto 4)
>>> (Objeto 2, Objeto 4)
>>> (Objeto 1, Objeto 2, Objeto 4)
>>>
>>> Para hacerlo en R me planteé el primer ejemplo: ¿en cuántas combinaciones
>>> sin repetición de los objetos anteriores, tomados de dos en dos, están
>>> presentes los elementos a y b (SÓLO a y b)?
>>>
>>> df <- as.data.frame(t(combn(c("a", "b", "c", "a,b", "a,c", "b,c",
>>> "a,b,c"),2)))
>>> df <- df[!grepl("c", df$V1),]
>>> df <- df[!grepl("c", df$V2),]
>>>
>>> El problema es que este código me resuelve este caso concreto, pero no
>>> otros similares. He intentado crear una función que me permita resolver
>>> otro casos, como por ejemplo el ejemplo 2, pero no doy con la forma
>>> adecuada de plantearlo.
>>>
>>> ¿Se os ocurre alguna forma?
>>>
>>> Muchas gracias!
>>>
>>> Jose Ignacio
>>>
>>>         [[alternative HTML version deleted]]
>>>
>>> _______________________________________________
>>> R-help-es mailing list
>>> R-help-es en r-project.org
>>> https://stat.ethz.ch/mailman/listinfo/r-help-es
>>>
>>
>>
>>
>> --
>> Saludos,
>> Carlos Ortega
>> www.qualityexcellence.es
>>
>
>


-- 
Saludos,
Carlos Ortega
www.qualityexcellence.es

	[[alternative HTML version deleted]]



Más información sobre la lista de distribución R-help-es