jueves, septiembre 26, 2019

Muestra aleatoria con Power Query

Para el ejemplo del post "BUSCARV o Combinar consultas" necesitaba crear una tabla con 10 productos elegidos aleatoriamente de una lista con más de 70 items. En Excel Clásico resolvemos la cuestión usando la función ALEATORIO() o la función ALEATORIO.ENTRE():

  1. asignamos un número aleatorio a cada fila, 
  2. cancelamos las fórmulas con Copiar--Pegar--Solo valores, 
  3. ordenamos la tabla en forma ascendente o descendente 
  4. elegimos las primeras 10 filas (o el número de filas que deseemos). 

¿Cómo lo haríamos con Power Query?  Contamos con la función Number.Random pero al usarla veremos que suceden cosas extrañas.

Veamos este ejemplo

Partimos de la lista completa, y creamos una consulta




Para agregar la columna con los números aleatorios usamos Agregar columna-Columna Personalizada de esta manera

y ahora nuestra consulta se verá así


Al ordenar la columna [Aleatorio] vemos que ésta es recalculada y por lo tanto no podemos ordenarla


Lo mismo sucede en Excel y la solución es cancelar las fórmulas como indicamos más arriba, En Power Query podemos intentar duplicar la columna y luego eliminar [Aleatorio] pero entonces veremos lo siguiente


¡Todas las filas de la columna muestran el mismo número aleatorio! No se trata de un "bug" sino de, hasta donde he logrado entender, una decisión de diseño de los ingenieros de Microsoft.
Lo mismo sucede si cargamos la consulta a una hoja de Excel inmediatamente después de agregar la columna [Aleatorio].

Hay varios caminos para resolver esta situación. En este post voy a mostrar dos de ellas.

1 - Usar la List.Random

En lugar de usar Number.Random usamos la función List,Random poniendo "1" como primer argumento


Expandimos la columna [Aleatorio] con la opción Expandir en nuevas filas y ordenamos la columna, en nuestro ejemplo en orden ascendente


Ahora podemos usar Inicio-Conservar Filas-Superiores


Eliminamos la columna [Aleatorio] y cargamos la consulta en una hoja de Excel o como "solo conexión".

El código completo de la consulta es

 let  
   Origen = Excel.CurrentWorkbook(){[Name="Lista_Productos"]}[Content],  
   #"Personalizada agregada" = Table.AddColumn(Origen, "Aleatorio", each List.Random(1)),  
   #"Se expandió Aleatorio" = Table.ExpandListColumn(#"Personalizada agregada", "Aleatorio"),  
   #"Filas ordenadas" = Table.Sort(#"Se expandió Aleatorio",{{"Aleatorio", Order.Ascending}}),  
   #"Conservar filas superiores" = Table.FirstN(#"Filas ordenadas",10)  
 in  
   #"Conservar filas superiores"  


2 - Usar la función Table.Buffer

Agregamos el paso con este función en el editor avanzado

Aleatorio = Table.Buffer(Table.AddColumn(Origen,"Aleatorio", each Number.Random()))


Ahora podemos ordenar la columna [Aleatorio] y dejar la cantidad de filas deseadas (10 en nuestro ejemplo). El código completo de la consulta es 

 let  
   Origen = Excel.CurrentWorkbook(){[Name="Lista_Productos"]}[Content],  
   Aleatorio = Table.Buffer(Table.AddColumn(Origen,"Aleatorio", each Number.Random())),  
   #"Filas ordenadas" = Table.Sort(Aleatorio,{{"Aleatorio", Order.Ascending}}),  
   #"Conservar filas superiores" = Table.FirstN(#"Filas ordenadas",10),  
   #"Columnas quitadas" = Table.RemoveColumns(#"Conservar filas superiores",{"Aleatorio"})  
 in  
   #"Columnas quitadas"  

La ventaja del primer método es que podemos usar la interfaz del usuario para escribir la función, lo cual es apropiado par usuarios que aún no están familiarizados con la edición del código en el Editor Avanzado.

No hay comentarios.:

Publicar un comentario

Nota: sólo los miembros de este blog pueden publicar comentarios.