Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Earn a 50% discount on the DP-600 certification exam by completing the Fabric 30 Days to Learn It challenge.

Reply
Syndicate_Admin
Administrator
Administrator

¿Cómo hacer redondeo personalizado en DAX?

Hola a todos

¡Aquí hay un cracker navideño para nuestros especialistas en DAX!

Quiero crear una medida DAX que calcule el porcentaje de valores por categoría en una tabla al total de esa tabla, con el siguiente redondeo personalizado:

- Todos los porcentajes deben redondearse al entero más cercano.

- Luego hay que identificar cuántos puntos porcentuales faltan para alcanzar el 100% en total.

- A continuación, estos puntos porcentuales deben sumarse cada uno a los porcentajes con la parte decimal más grande en orden descendente.

Tenga en cuenta que el conjunto de datos es enorme, por lo que el impacto del cálculo de DAX debe limitarse tanto como sea posible.

Así, por ejemplo:

Categoría A: 26,98%,
Categoría B: 34,78%,
Categoría C: 38,24%

Redondeado hacia abajo esto se convierte en:

Categoría A: 26
Categoría B: 34
Categoría C: 38
26 + 34 + 38 = 98 -> 2 puntos porcentuales faltantes

Estos puntos porcentuales faltantes deben asignarse a los 2 porcentajes con la parte decimal más alta:
Categoría A: 27
Categoría B: 35
Categoría C: 38
27 + 35 + 38 = 100%

¿Cómo puedo hacer esto con DAX? Creo que se requiere alguna iteración y / o almacenamiento en búfer, pero ¿cómo lo hago?

@parry2k tal vez lo sepas?

1 ACCEPTED SOLUTION

¡Genial, eso funcionó! Muchas gracias, muy apreciado 🙂

Y agregué una alternativa para SWITCH en caso de que no sea necesario redondear nada (en el improbable caso de que todos sean números con 0 decimales)

View solution in original post

33 REPLIES 33

Puedo preparar Power Query M para la solución de redondeo o redondeo, pero sin este requisito adicional para dividir este valor % entre la categoría 2 o 3. Arrepentido. 🙂

Veo que trabajaste un vínculo con los datos de ejemplo. Consulte esta expresión de medida actualizada que utiliza RAND para romper el empate.

AdjValue = 
VAR vThisVal = [AvgVal]
VAR vThisCategory1 =
    MIN ( T1[Category1] )
VAR tNew =
    ADDCOLUMNS (
        CALCULATETABLE ( DISTINCT ( T1[Category1] ), REMOVEFILTERS ( T1[Category1] ) ),
        "cOrigVal", [AvgVal]
    )
VAR tRoundMod =
    ADDCOLUMNS (
        tNew,
        "cRD", ROUNDDOWN ( [cOrigVal], 0 ),
        "cMod", MOD ( [cOrigVal], 1 ),
        "cRand", RAND()/1000
    )
VAR vThisModRand = SUMX(FILTER(tRoundMod, T1[Category1] = vThisCategory1), [cMod] + [cRand])
VAR vGapTo100 =
    100 - SUMX ( tRoundMod, [cRD] )
VAR vModRank =
    RANKX ( tRoundMod, [cMod] + [cRand], vThisModRand, DESC )
VAR vResult =
    IF ( vModRank <= vGapTo100, ROUNDUP ( vThisVal, 0 ), ROUNDDOWN ( vThisVal, 0 ) )
RETURN
    vResult

ppm1_0-1671893166434.png

Palmadita

Hola Pat @ppm1 probé esto en mi conjunto de datos de prueba simple y noté que los resultados son correctos. Sin embargo, parece que los valores asignados a los empates (B y C en la Categoría 1) son muy inestables, es decir, cuando actualizo el informe los valores cambian cada vez, ver capturas de pantalla a continuación. ¿Tal vez esto tiene algo que ver con los resultados almacenados en una tabla virtual?

PunchBird_1-1671981140878.png

Después de la actualización:

PunchBird_0-1671981109941.png

PunchBird_2-1671981182183.png

PunchBird_3-1671981198177.png

Entiendo su punto. Dijiste que quieres redondear hacia abajo, así que ...

En los datos originales, agregue una nueva columna DAX:

Redondeo = REDONDEO ('Muestra'[Porcentaje],0)
A continuación , agregue una nueva columna
Nuevo porcentaje =
var licznik = [Redondeo]
var mianownik = CALCULATE(SUMA('Muestra'[Redondeo]),ALLEXCEPT('Muestra','Muestra'[Categoría2]))
return DIVIDE(licznik,mianownik)

Resultado en tabla:

bolfri_0-1671975442672.png

Como puede ver, el 2% faltante se dividió entre la Categoría A y D.

Pero podemos usar RoundingUp para dar este 2% faltante a la categoría B y C.

Otra vez. Agregue una nueva columna:

RedondeoArriba = REDONDEO([Porcentaje],0)

Y otra nueva columna:

Nuevo porcentaje UP =
var licznik = [Redondeo]
var mianownik = CALCULATE(SUMA('Muestra'[Redondeo]),ALLEXCEPT('Muestra','Muestra'[Categoría2]))
return DIVIDE(licznik,mianownik)

Resultado en tabla:

bolfri_2-1671975787711.png

En función de la ruta que elijas obtendrás diferentes resultados 🙂 Elige el que prefieras.

Lo siento, acabo de notar que he usado palabras polacas para variables. Puedes cambiarlo por el que quieras.

licznik = numerador

mianowni= denominador

LO SIENTO MUCHO 😂

Hola Pat, gracias por tu ayuda. Copié su medida en mis datos de prueba, pero no parece redondear correctamente en Categoría2 para X (donde hay un empate), ver captura de pantalla, porque 44 + 12 + 12 + 31 = 99

Un 12 debería convertirse en 13 como también se muestra en su ejemplo, pero no sucede en el mío.

¿Podría compartir su pbix para que pueda echar un vistazo a lo que hizo? ¡Muchas gracias!

PunchBird_0-1671965153004.png

Syndicate_Admin
Administrator
Administrator

@PunchBird ¡Ah! por lo que la distribución del resto es dinámica.

¡Sí, por supuesto!

Syndicate_Admin
Administrator
Administrator

Aquí hay una expresión de medida que muestra una forma de hacerlo. Tendrá que tener cuidado con los empates en los valores de MOD y cuando los valores sumen >100 (pero puede adaptar esta medida para hacerlo).

ppm1_0-1671815036664.png

AdjValue =
VAR vThisCategory =
    MIN ( T1[Category] )
VAR vThisVal = [AvgVal]
VAR vThisRD =
    ROUNDDOWN ( vThisVal, 0 )
VAR vThisMod =
    MOD ( vThisVal, 1 )
VAR tNew =
    ADDCOLUMNS ( ALL ( T1[Category] ), "cOrigVal", [AvgVal] )
VAR tRoundMod =
    ADDCOLUMNS (
        tNew,
        "cRD", ROUNDDOWN ( [cOrigVal], 0 ),
        "cMod", MOD ( [cOrigVal], 1 )
    )
VAR vGapTo100 =
    100 - SUMX ( tRoundMod, [cRD] )
VAR vModRank =
    RANKX ( SELECTCOLUMNS ( tRoundMod, "cMod2", [cMod] ), [cMod2], vThisMod, DESC )
VAR vResult =
    IF ( vModRank <= vGapTo100, ROUNDUP ( vThisVal, 0 ), ROUNDDOWN ( vThisVal, 0 ) )
RETURN
    vResult

Palmadita

Syndicate_Admin
Administrator
Administrator

@PunchBird Hice esto (ver más abajo). PBIX está conectado.

Measure = 
    VAR __Table = 
        GENERATE(
            SUMMARIZE(ALLSELECTED('Table'),'Table'[Category]),
                VAR __Value = [Percentage]
                VAR __RD = ROUNDDOWN(__Value,2)
                VAR __Decimal = __Value - __RD
            RETURN
                ROW(
                    "Value", __Value,
                    "RD", __RD,
                    "Decimal", __Decimal
                )
        )
    VAR __MaxDecimal = MAXX(__Table,[Decimal])
    VAR __MaxCategory = MAXX(FILTER(__Table, [Decimal] = __MaxDecimal),[Category])
    VAR __Category = MAX('Table'[Category])
    VAR __Result = IF(__Category = __MaxCategory, ROUNDUP([Percentage],2), ROUNDDOWN([Percentage],2))
RETURN
    __Result

@Greg_Deckler gracias por su cálculo. Probé esto en mis datos de prueba (ver más abajo para un ejemplo más elaborado), pero aparentemente su cálculo solo funciona cuando hay un punto porcentual para agregar. Si hay dos puntos porcentuales que deben agregarse, el total es del 99%, vea también la captura de pantalla a continuación

PunchBird_0-1671975601952.png

Syndicate_Admin
Administrator
Administrator

@PunchBird Interesante pregunta. ¿El resto siempre se distribuye por igual a los dos principales contribuyentes?

@parry2k el resto debe distribuirse en orden descendente. Entonces, si el resto es 1, se asigna al porcentaje que tenía la parte decimal más grande, y si el resto es 2, se asigna a los dos porcentajes superiores que tenían la parte decimal más grande.

Helpful resources

Announcements
PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.