Menu

Añadir y transformar columnas en R (mutate y R base)

Cómo añadir, transformar y eliminar columnas de un data frame: df$new <- ..., ifelse() para columnas condicionales, transform(), y el mutate() de dplyr con case_when().

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Añadir una columna: df$new <- valor

Para añadir una columna en R base, asigna a un nombre que aún no exista. El valor suele calcularse a partir de columnas que sí existen:

Pasaron dos cosas. orders$total recibió un vector completo: price * qty se calcula para todas las filas a la vez, porque la aritmética en R es vectorizada. orders$currency recibió un valor único, que R recicló a las cuatro filas. Cualquier otra longitud es un error (replacement has 3 rows, data has 4), que es R protegiéndote de una columna desalineada.

Esto funciona porque un data frame es una lista de columnas de igual longitud: asignar un nuevo elemento con nombre hace crecer la lista. La documentación de data frames desgrana ese modelo.

Columnas condicionales: ifelse()

Una columna cuyo valor depende de una condición pide ifelse(), el primo vectorizado de if. Recibe un vector entero de condiciones y devuelve un valor por fila:

¿Por qué no un if normal? Porque if evalúa exactamente un TRUE/FALSE - si le pasas una columna, da error (the condition has length > 1). ifelse(test, yes, no) comprueba cada elemento y elige por fila. Para tres o más resultados puedes anidar:

Anidar a dos niveles está bien; tres o más se convierte en una pirámide - ese es exactamente el trabajo para el que se creó el case_when() de dplyr (más abajo). El if/else de valor único se cubre en la documentación de if-else.

Varias columnas a la vez: transform()

El transform() de R base añade varias columnas en una sola llamada, con nombres de columna a secas:

Fíjate en que transform() devuelve un data frame nuevo - debes reasignar el resultado, mientras que df$new <- ... modifica en el sitio. Una limitación: las expresiones dentro de una misma llamada a transform() no se ven entre sí, así que discount = ifelse(total > 50, ...) falla ahí (total aún no existe). Hazlo en dos pasos - o con mutate(), que sí lo permite.

Modificar vs crear

La misma sintaxis de asignación sobrescribe una columna existente - que la columna existiera de antemano es la única diferencia:

Vale la pena detenerse en esto: R no te avisa cuando sobrescribes una columna. Una errata como df$prise <- round(df$price, 2) crea silenciosamente una columna nueva en lugar de arreglar la vieja. Después de una transformación, haz print() o str() del data frame y confirma que cambiaste lo que querías cambiar.

Eliminar una columna

Asigna NULL para borrar:

La columna desaparece, sin ceremonias. Para eliminar varias, df[, c("a", "b")] (conservas lo que listas) suele ser más claro que NULLs repetidos.

La forma dplyr: mutate()

El verbo de dplyr para todo lo anterior es mutate(). Los fragmentos de abajo son estáticos - el sandbox solo ejecuta R base - pero así se ven las mismas operaciones:

library(dplyr)

orders |>
    mutate(
        total    = price * qty,
        big      = total > 50        # can use total, defined one line up
    )

Dos ventajas sobre R base. Primera, las columnas definidas en el mismo mutate() pueden referenciarse entre sí, en orden - lo que transform() rechaza. Segunda, los ayudantes condicionales son mejores que los ifelse() anidados:

students |>
    mutate(
        grade = if_else(score >= 60, "pass", "fail"),
        band  = case_when(
            score >= 85 ~ "high",
            score >= 60 ~ "mid",
            .default    = "low"
        )
    )

if_else() es un ifelse() más estricto (ambas ramas deben ser del mismo tipo - atrapa errores reales). case_when() se lee como una lista plana de pares condición ~ valor comprobados de arriba abajo, con .default como respaldo - el reemplazo legible de la pirámide de ifelse(). Como todo verbo de dplyr, mutate() devuelve un data frame nuevo; consulta la introducción a dplyr para ver cómo se encadena con el resto.

Lo que te llevas

  • df$new <- expresión añade una columna; la expresión se ejecuta para todas las filas a la vez.
  • ifelse(test, yes, no) construye columnas condicionales; el if normal no puede.
  • transform() añade varias columnas por llamada pero no se ven entre sí; mutate() sí.
  • La misma asignación sobrescribe en silencio - revisa la ortografía después de una transformación.
  • df$col <- NULL elimina una columna; case_when() sustituye las pirámides de ifelse() anidados.

A continuación: renombrar columnas - names(), el idioma robusto de base y el rename() de dplyr.

Preguntas frecuentes

¿Cómo añado una nueva columna a un data frame en R?

Asigna a un nombre de columna que aún no exista: df$total <- df$price * df$qty. R crea la columna en el acto. El valor puede ser un valor único (reciclado a cada fila) o un vector calculado a partir de otras columnas, siempre que su longitud coincida con el número de filas.

¿Cómo creo una columna condicional en R?

Usa el ifelse() vectorizado: df$grade <- ifelse(df$score >= 60, "pass", "fail") comprueba todas las filas a la vez. No uses un if normal - maneja una sola condición, no una columna. Para más de dos resultados, anida llamadas a ifelse() o usa el case_when() de dplyr.

¿Qué hace mutate() en R?

mutate() es el verbo de dplyr para añadir o transformar columnas: df |> mutate(total = price * qty) devuelve una copia del data frame con la nueva columna. Puede definir varias columnas en una sola llamada, y las columnas posteriores pueden usar las anteriores definidas en el mismo mutate.

¿Cómo elimino una columna de un data frame en R?

Asígnale NULL: df$notes <- NULL elimina la columna en el sitio. En dplyr, select(-notes) devuelve una copia sin ella.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR