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 multiplicar columnas de un tibble por filas o columnas correspondientes de otro tibble en R?

Estoy intentando multiplicar columnas de un tibble por filas de otro tibble en R. Intenté usar las funciones sweep y match desde aquí, pero solo utiliza un vector (una columna del segundo tibble). Una muestra pequeña de mi primer conjunto de datos se ve así:

tmode chvalue purpose sov ownership age16 joint atwork sovtime
SHARED 2.06 eat 0 0 0 1 0 0.12
SHARED 2.19 eat 0 0 0 0 0 0.08
WALK 2.45 eat 0 1 0 1 0 0.02
PAY 2.30 eat 0 0 0 0 0 0.18
PAY 2.09 eat 0 0 0 0 0 0.12
ALONE 1.82 work 0 0 0 0 0 0.03
SHARED 0.2 work 0 0 0 1 0 0.14

Y una muestra pequeña del segundo conjunto de datos se ve así:

Expression ALONE SHARED WALK PAY
sov -999 0 1 0
ownership -999 0 1 0
age16 -999 0 1 0
joint -999 0 1 0
atwork 1 0 0 0
sovtime 1 0 0 0

Los conjuntos de datos reales son muy grandes (1000 filas y 100k columnas). Agradecería si alguien pudiera ayudarme a encontrar la solución.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para multiplicar columnas de un tibble por filas de otro tibble en R, puedes utilizar la función mapply. Aquí hay un código de ejemplo que coincide los nombres de columna de los dos conjuntos de datos y los multiplica:

    library(tidyverse)
    
    # establecer semilla para reproducibilidad
    set.seed(123)
    
    # crear tibbles de muestra
    df1 <- tibble(
      t_mode = sample(c("SHARED", "WALK", "PAY", "ALONE"), 10, replace = TRUE),
      ch_value = 20 + rnorm(10, sd = 5),
      purpose = sample(c("eat", "work"), 10, replace = TRUE),
      sov = sample(0:1, 10, replace = TRUE),
      ownership = sample(0:1, 10, replace = TRUE),
      age_16 = sample(0:1, 10, replace = TRUE),
      joint = sample(0:1, 10, replace = TRUE),
      atwork = sample(0:1, 10, replace = TRUE),
      sov_time = runif(10)
    )
    
    df2 <- tibble(
      Expression = c("sov", "ownership", "age_16", "joint", "atwork", "sov_time"),
      ALONE = c(-999, -999, -999, -999, 1, 1),
      SHARED = c(0, 0, 0, 0, 0, 0),
      WALK = c(1, 1, 1, 1, 0, 0),
      PAY = c(0, 0, 0, 0, 0, 0)
    )
    
    # multiplicar columnas de df1 por filas de df2
    result <- df1 %>%
      select(-purpose) %>% # excluir columnas no numéricas
      mutate(across(.cols = everything(), .fns = list(multiplied = ~ mapply(function(x, y) { x*y }, ., df2[[match(str_replace(cur_column(), "_multiplied", ""), df2$Expression)]])))) %>%
      select(-ends_with("_multiplied")) # excluir columnas multiplicadas
    
    head(result)
    #> # A tibble: 6 x 9
    #>   t_mode ch_value   sov ownership age_16 joint atwork sov_time
    #>   <chr>     <dbl> <dbl>     <dbl>  <dbl> <dbl>  <dbl>    <dbl>
    #> 1 SHARED     22.3     0         0      0     0      0  0      
    #> 2 SHARED     21.4     0         0      0     0      0  0      
    #> 3 WALK       15.6     0         1      0     0      0  0.282  
    #> 4 PAY        32.6     0         0      0     0      0  0.0639 
    #> 5 PAY        25.4     0         0      0     0      0  0.0649 
    #> 6 ALONE      33.3 -999.        0      0     0      0  0.0338
    

    En este código de ejemplo, primero excluimos columnas no numéricas (es decir, purpose) de df1, y luego utilizamos mutate, across y mapply para multiplicar cada columna de df1 por su correspondiente fila en df2. Específicamente, utilizamos match para coincidir los nombres de columna de df1 (es decir, t_mode, ch_value, etc.) con los nombres de fila de df2 (es decir, sov, ownership, etc.), y luego utilizamos mapply para multiplicar cada valor en la columna de df1 por su valor correspondiente en la fila de df2. Finalmente, excluimos las columnas multiplicadas (es decir, aquellas que terminan con _multiplied) del resultado.

    Ten en cuenta que este código asume que los nombres de columna de df1 coinciden con los nombres de fila de df2 (excepto por el sufijo _multiplied), y que no hay columnas/filas faltantes o adicionales. Si tus conjuntos de datos reales tienen estructuras diferentes, es posible que necesites ajustar el código en consecuencia. También ten en cuenta que dado que tus conjuntos de datos reales son muy grandes, este código puede tardar algún tiempo en ejecutarse.

Comments are closed.