mutate(across) para generar múltiples columnas nuevas en tidyverse
Por lo general, tengo que realizar cálculos equivalentes en una serie de variables/columnas que pueden ser identificadas por su sufijo (que van, digamos, desde a hasta _i) y guardar el resultado en nuevas variables/columnas. Los cálculos son equivalentes, pero varían entre las variables utilizadas en los cálculos. Estas, nuevamente, pueden ser identificadas por el mismo sufijo (a hasta _i). Así que básicamente lo que quiero lograr es lo siguiente:
newvar_a = (oldvar1_a + oldvar2_a) - z
...
newvar_i = (oldvar1_i + oldvar2_i) - z
Esto es lo más lejos que llegué:
mutate(across(c(oldvar1_a:oldvar1_i), ~ . - z, .names = "{col}_new"))
Así que puedo “recorrer” oldvar1a hasta oldvar1i, restarles z y guardar los resultados en nuevas columnas nombradas oldvar1anew hasta oldvar1inew. Sin embargo, no soy capaz de incluir oldvar2a hasta oldvar2i en los cálculos, ya que R no los recorrerá automáticamente. (Además, aún tendría que renombrar las nuevas columnas).
Encontré una forma de lograr el resultado utilizando un bucle for. Sin embargo, esto definitivamente no parece ser la forma más eficiente y directa de hacerlo:
for (i in letters[1:9]) {
oldvar1_x <- paste0("oldvar1_", i)
oldvar2_x <- paste0("oldvar2_", i)
newvar_x <- paste0("newvar_", i)
df <- df %>%
mutate(!!sym(newvar_x) := (!!sym(oldvar1_x) + !!sym(oldvar2_x)) - z)
}
Así que me gustaría saber si/hay alguna forma de hacer que mutate(across) recorra múltiples columnas que pueden ser identificadas por sufijos (como en el ejemplo anterior).
davy.ai
Para realizar cálculos equivalentes en una serie de variables identificadas por su sufijo, podemos usar el paquete
tidyselect
para seleccionar columnas basadas en su sufijo, y luego aplicar el cálculo usandomutate
. Aquí hay un ejemplo de código:“`{r}
library(tidyverse)
datos de ejemplo
df <- tibble(oldvar1_a = 1:10,
oldvar2_b = 11:20,
oldvar1_i = 91:100,
oldvar2_i = 101:110)
z <- 5
seleccionar columnas por sufijo y aplicar cálculo
df <- df %>%
mutate(across(ends_with(“_a”):ends_with(“_i”),
~(. + !!sym(str_replace(cur_column(), “(oldvar1|oldvar2)”, “oldvar2”)) – z),
.names = “{.col}_new”))
A tibble: 10 x 8
oldvar1_a oldvar2_b oldvar1_i oldvar2_i oldvar1_a_new oldvar2_b_new oldvar1_i_new oldvar2_i_new
1 1 11 91 101 7 117 177 197
2 2 12 92 102 8 118 178 198
3 3 13 93 103 9 119 179 199
4 4 14 94 104 10 120 180 200
5 5 15 95 105 11 121 181 201
6 6 16 96 106 12 122 182 202
7 7 17 97 107 13 123 183 203
8 8 18 98 108 14 124 184 204
9 9 19 99 109 15 125 185 205
10 10 20 100 110 16 126 186 206
“`