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.
davy.ai
Una posible solución a este problema es utilizar una combinación de las funciones
mutate_at
,lead
ycoalesce
del paquetedplyr
, 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ónvars
. En este caso, seleccionamos todas las columnas que comienzan con “iter” utilizando la funciónstarts_with
.La función aplicada a cada columna seleccionada se define utilizando la notación de fórmula
~
. Definimos una función personalizadadiff_func
que toma dos argumentos: los valores de la columnax
y el desplazamiento (n
).Dentro de
diff_func
, utilizamos la funciónlead
para obtener el valor de la siguiente columna, con un desplazamiento den
. Si la siguiente columna falta (NA
), utilizamos la funcióncoalesce
para devolverNA
en lugar deNA - 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.