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.

Tomando diferencias en movimiento de columnas en un tibble de R para un número arbitrario de columnas.

Quiero calcular las diferencias por columna. Normalmente usaría…

df %>%
  mutate(diff_iter2 = iter2 - iter1,
         diff_iter3 = iter3 - iter2)

Pero… me gustaría:
1) acomodar un número arbitrario de columnas y
2) tratar los NA de la siguiente manera:
    si el número al que le estamos restando es NA, entonces el resultado debería ser NA. Por ejemplo, NA – 11 = NA
    si el número que estamos restando es NA, entonces ese NA se trata efectivamente como un 0. Por ejemplo, 35 – NA = 35

El resultado debería verse así…

   group subgroup iter1 iter2 iter3 diff_iter2 diff_iter3
   <chr> <chr>    <int> <dbl> <int>      <dbl>      <dbl>
 1 a     adam         1    13    25         12         12
 2 a     boy          2    14    26         12         12
 3 a     charles      3    15    27         12         12
 4 a     david        4    16    28         12         12
 5 b     adam         5    17    29         12         12
 6 b     boy          6    18    30         12         12
 7 b     charles      7    19    31         12         12
 8 b     david        8    20    32         12         12
 9 c     adam         9    21    33         12         12
10 c     boy         10    22    34         12         12
11 c     charles     11    NA    35         NA         35
12 c     david       12    24    NA         12         NA

Originalmente, este df estaba en formato largo, pero el problema era que creo que la función lag() opera en posición dentro de los grupos y todos los grupos no son iguales porque faltan algunos registros (de ahí el NA en la tabla más ancha que se muestra arriba).

Si empezamos con el formato largo estaría bien, pero luego por favor asuma que los registros mostrados arriba con valores NA no existirían en ese dataframe más largo.

Cualquier ayuda es apreciada.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible solución a este problema es utilizar una combinación de las funciones mutate_at, lead y coalesce del paquete dplyr, como se muestra a continuación:

    “`{r}
    library(dplyr)

    definir una función personalizada para calcular las diferencias

    diff_func <- function(x, n) {
    lead_val <- lead(x, n = n)
    coalesce(lead_val – x, NA)
    }

    aplicar la función a las columnas seleccionadas utilizando mutate_at

    df %>%
    mutate_at(vars(starts_with(“iter”)), ~ diff_func(., n = 1)) %>%
    rename_at(vars(starts_with(“iter”)), ~ paste0(“diff_”, .)) # renombrar las nuevas columnas
    “`

    Explicación:

    • mutate_at aplica una función a una selección de columnas, especificadas utilizando la función vars. En este caso, seleccionamos todas las columnas que comienzan con “iter” utilizando la función starts_with.
    • La función aplicada a cada columna seleccionada se define utilizando la notación de fórmula ~. Definimos una función personalizada diff_func que toma dos argumentos: los valores de la columna x y el desplazamiento (n).

    • Dentro de diff_func, utilizamos la función lead para obtener el valor de la siguiente columna, con un desplazamiento de n. Si la siguiente columna falta (NA), utilizamos la función coalesce para devolver NA en lugar de NA - x.

    • Finalmente, renombramos las nuevas columnas utilizando la función rename_at, añadiendo el prefijo “diff_” a cada nombre de columna seleccionada.

    El resultado debería ser una tabla con nuevas columnas para las diferencias entre iteraciones consecutivas, acomodando un número arbitrario de columnas y manejando los valores faltantes según lo solicitado.

Comments are closed.