es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo hacer una resta basada en múltiples columnas – R

Tengo una base de datos enorme actualizada mensualmente, aquí intentaré crear un ejemplo.

Año Mes UF Seg Fai Valor LinProd Marca
2021 Nov SP Construcción B 1 Prod1 Comp.1
2021 Nov SP Construcción B 7 Prod1 Mercado
2021 Nov SP Construcción C 5 Prod2 Mercado
2021 Nov SP Construcción B 2 Prod1 Comp.2
2021 Nov MG Ubicación A 4 Prod2 Mercado
2021 Nov MG Minería A 8 Prod4 Mercado
2021 Nov MG Minería B 16 Prod4 Mercado
2021 Nov MG Minería F 2 Prod4 Mercado
2021 Nov MG Minería A 3 Prod4 Comp.1
2021 Nov MG Minería B 8 Prod4 Comp.2
2021 Nov MG Minería F 1 Prod4 Comp.2

Esta base de datos se exporta desde Excel, lo que necesito hacer básicamente es una resta, Market-(Comp.1+Comp2). Respetando todas las columnas. El resultado que necesito es algo así:

Año Mes UF Seg Fai Valor LinProd Marca
2021 Nov SP Construcción B 4 Prod1 Mercado
2021 Nov SP Construcción C 5 Prod2 Mercado
2021 Nov MG Ubicación A 4 Prod2 Mercado
2021 Nov MG Minería A 5 Prod4 Mercado
2021 Nov MG Minería B 8 Prod4 Mercado
2021 Nov MG Minería F 1 Prod4 Mercado

Donde no hay una resta, simplemente se imprimirá como estaba antes, como se puede ver en la línea 5 de la primera tabla y en la línea 3 de la segunda tabla, no había ningún producto de Comp.1 y Comp.2, por lo que no ocurrió nada con ellos.

He intentado este código:

t<-as.data.frame(read_xlsx("C:/Users/lucas/Documents/Base.xlsx"))

c=as.data.frame(filter(t,Brand=="Comp.1"))
c$Value=c$Value*-1

ti=as.data.frame(filter(t,Brand=="Market"))

n=as.data.frame(filter(t,Brand=="Comp.2"))
n$Value=n$Value*-1

mar=rbind(ti,c,n)
ag=aggregate(mar$Value,by=list(mar$Brand,mar$Month,mar$UF, mar$Seg,mar$Fai,mar$LinProd),FUN = sum)

write_xlsx(ag,"C:/Users/lucas/Documents/Test.xlsx" )
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para restar los valores de Comp.1 y Comp.2 de la columna Market, un enfoque es filtrar primero las filas con Brand igual a Comp.1 y Comp.2, luego multiplicar sus valores por -1 para cambiar el signo. A continuación, podemos unir estas filas junto con las filas de Market usando rbind(). Por último, agrupamos el data frame resultante por las columnas que queremos mantener (Brand, Month, UF, Seg, Fai, LinProd) y usamos la función sum() para agregar la columna Value.

    Aquí está el código con algunas modificaciones menores para que funcione:

    library(readxl)
    
    # Leer los datos
    t <- read_excel("C:/Users/lucas/Documents/Base.xlsx")
    
    # Filtrar las filas con Brand igual a Comp.1 y Comp.2
    c <- subset(t, Brand == "Comp.1")
    c$Value <- -1 * c$Value
    
    n <- subset(t, Brand == "Comp.2")
    n$Value <- -1 * n$Value
    
    # Unir las filas y mantener solo las columnas necesarias
    mar <- rbind(subset(t, Brand == "Market"), c, n)
    mar <- mar[, c("Year", "Month", "UF", "Seg", "Fai", "Value", "LinProd", "Brand")]
    
    # Agrupar por las columnas deseadas y agregar la columna Value
    ag <- aggregate(Value ~ Brand + Month + UF + Seg + Fai + LinProd, data = mar, FUN = sum)
    
    # Escribir el resultado en un nuevo archivo
    write_excel_csv(ag, "C:/Users/lucas/Documents/Test.csv")
    

    Ten en cuenta que utilicé subset() en lugar de filter() del paquete dplyr, ya que parece que no estás usando dplyr en tu código original. Además, write_xlsx() no parece ser un nombre de función válido, así que lo cambié por write_excel_csv(), que es una función del paquete readxl que puede escribir archivos de Excel en formato CSV.

    El archivo de salida resultante debería tener el formato deseado con los valores de Market ajustados restando los valores de Comp.1 y Comp.2.

Comments are closed.