Fórmulas de Excel en R: guía para usuarios de Excel
Si sabes usar Excel, ya sabes qué quieres hacer con tus datos: buscar valores, sumar según una condición, montar una tabla dinámica o separar una columna de texto. Esta guía te enseña cómo hacerlo en R, con una gran tabla de funciones de Excel y sus equivalentes en R base y dplyr, ejemplos cortos de las fórmulas más usadas sobre una pequeña tabla de ventas, cómo leer y guardar archivos de Excel y algunos consejos para que el cambio te resulte más fácil.
De celdas a vectores: qué cambia al pasar a R
La mayoría de fórmulas de Excel tienen un equivalente directo en R. Lo que cambia es la forma de pensar en los datos:
- Celdas → vectores y data frames. En Excel trabajas con celdas (
B2) y rangos (B2:B100). En R trabajas con columnas completas, que son vectores, y con tablas, que son data frames. Te refieres a una columna por su nombre (ventas$precio), no por su posición. - Fórmulas arrastradas → operaciones vectorizadas. En Excel escribes
=E2*F2y la arrastras hacia abajo. En R,ventas$unidades * ventas$preciomultiplica las dos columnas elemento a elemento en una sola operación, da igual que tengan 10 filas o 10 millones. - Hojas → data frames. Cada hoja con una tabla pasa a ser un data frame. En lugar de hacer referencia a
Productos!A:D, trabajas con un objeto llamadoproductos, y puedes tener todos los que quieras en memoria a la vez. - Clics → código. Ordenar, filtrar o quitar duplicados no son opciones de un menú sino funciones. Cuesta más la primera vez, pero el código se puede volver a ejecutar con los datos del mes siguiente sin ningún esfuerzo.
Hay una última diferencia importante: R no recalcula automáticamente. Si cambias un valor de la columna precio, la columna total no se actualizará hasta que vuelvas a ejecutar el código que la calcula. Por eso es mejor guardar todos los pasos en un script y ejecutarlo de principio a fin.
Funciones de Excel y sus equivalentes en R
La siguiente tabla recoge las funciones y herramientas de Excel más utilizadas, con su nombre en español y en inglés (muchos usuarios tienen Excel en inglés), su equivalente en R base y en el tidyverse (dplyr, tidyr y stringr) y el tutorial donde puedes aprender más sobre cada una.
| Excel (español / inglés) | R base | dplyr / tidyverse | Tutorial |
|---|---|---|---|
BUSCARV / VLOOKUP, BUSCARX / XLOOKUP, INDICE + COINCIDIR / INDEX + MATCH |
t$col[match(x, t$clave)], merge(all.x = TRUE) |
left_join() |
BUSCARV en R |
SUMAR.SI / SUMIF, SUMAR.SI.CONJUNTO / SUMIFS |
sum(x[cond]), tapply(), aggregate() |
group_by() + summarise(sum()) |
CONTAR.SI y SUMAR.SI en R |
CONTAR.SI / COUNTIF, CONTAR.SI.CONJUNTO / COUNTIFS |
sum(cond), table() |
count() |
CONTAR.SI y SUMAR.SI en R |
PROMEDIO.SI / AVERAGEIF, PROMEDIO.SI.CONJUNTO / AVERAGEIFS |
mean(x[cond]), tapply() |
group_by() + summarise(mean()) |
CONTAR.SI y SUMAR.SI en R |
| Tabla dinámica / Pivot table | tapply(), xtabs(), aggregate() |
summarise() + pivot_wider() |
Tablas dinámicas en R |
SI / IF |
ifelse() |
if_else() |
ifelse en R |
SI.CONJUNTO / IFS, SI anidados |
ifelse() anidados, cut() |
case_when() |
case_when |
SI.ERROR / IFERROR, SI.ND / IFNA |
ifelse(is.na(x), y, x), tryCatch() |
coalesce() |
tryCatch |
ESBLANCO / ISBLANK |
is.na() |
is.na(), drop_na() |
Valores NA |
CONCATENAR / CONCATENATE, CONCAT, & |
paste(), paste0() |
str_c() |
paste |
UNIRCADENAS / TEXTJOIN |
paste(x, collapse = ", ") |
str_flatten() |
paste |
IZQUIERDA / LEFT, DERECHA / RIGHT, EXTRAE / MID |
substr(), substring() |
str_sub() |
substring |
LARGO / LEN |
nchar() |
str_length() |
nchar |
ESPACIOS / TRIM |
trimws() |
str_squish() |
trimws |
MAYUSC / UPPER, MINUSC / LOWER, NOMPROPIO / PROPER |
toupper(), tolower() |
str_to_upper(), str_to_title() |
toupper y tolower |
SUSTITUIR / SUBSTITUTE |
gsub(), sub() |
str_replace_all() |
gsub y sub |
ENCONTRAR / FIND, HALLAR / SEARCH |
grepl(), regexpr() |
str_detect(), str_locate() |
grepl y grep |
| Texto en columnas / Text to columns | strsplit() |
separate_wider_delim() |
Texto en columnas en R |
| Quitar duplicados / Remove duplicates | unique(), duplicated() |
distinct() |
Eliminar duplicados |
| Ordenar / Sort | df[order(df$x), ] |
arrange() |
Ordenar en R, arrange |
| Filtro / Filter | df[cond, ], subset() |
filter() |
filter, subset |
TRANSPONER / TRANSPOSE |
t() |
pivot_longer(), pivot_wider() |
Operaciones con matrices, pivot_longer y pivot_wider |
REDONDEAR / ROUND, REDONDEAR.MAS / ROUNDUP, REDONDEAR.MENOS / ROUNDDOWN |
round(), ceiling(), floor(), trunc() |
Las mismas funciones | Redondear números |
SUMA / SUM, PROMEDIO / AVERAGE, MEDIANA / MEDIAN |
sum(), mean(), median() |
summarise() |
Media, mediana |
MIN, MAX |
min(), max() |
summarise() |
max y min |
DESVEST / STDEV, DESVEST.M / STDEV.S, VAR |
sd(), var() |
summarise() |
Desviación típica |
CONTAR / COUNT, CONTARA / COUNTA |
sum(!is.na(x)), length() |
n() |
length |
ALEATORIO / RAND, ALEATORIO.ENTRE / RANDBETWEEN |
runif(), sample() |
slice_sample() |
sample, runif |
HOY / TODAY, AHORA / NOW |
Sys.Date(), Sys.time() |
lubridate::today() |
Sys.Date y Sys.time |
SIFECHA / DATEDIF, diferencias de fechas |
difftime(), d2 - d1 |
lubridate |
Fechas en R |
Abrir un archivo .xlsx |
readxl::read_excel() |
read_excel() |
Leer archivos de Excel |
Guardar como .xlsx o CSV |
writexl::write_xlsx(), write.csv() |
write_xlsx() |
Exportar datos |
La columna del tidyverse usa funciones de dplyr (left_join, summarise, case_when…), tidyr (pivot_wider, separate_wider_delim) y stringr (las funciones str_*). No las necesitas para trabajar en R, pero hacen que el código sea más fácil de leer, sobre todo combinadas con el operador pipe %>%.
Fórmulas de Excel en R: ejemplos
En este apartado verás la versión en R de las fórmulas que más escriben los usuarios de Excel. Todos los ejemplos usan la siguiente tabla de ventas, que en Excel sería una hoja con ocho filas y seis columnas:
ventas <- data.frame(
fecha = as.Date(c("2026-01-12", "2026-01-25", "2026-02-03", "2026-02-18",
"2026-03-04", "2026-03-15", "2026-03-27", "2026-04-08")),
comercial = c("Ana Gil", "Luis Pardo", "Ana Gil", "Marta Ruiz",
"Luis Pardo", "Marta Ruiz", "Ana Gil", "Luis Pardo"),
zona = c("Norte", "Sur", "Norte", "Sur", "Sur", "Norte", "Norte", "Sur"),
producto = c("Portátil", "Móvil", "Móvil", "Portátil", "Tablet", "Móvil", "Tablet", "Portátil"),
unidades = c(2, 5, 3, 1, 4, 6, 2, 3),
precio = c(950, 420, 420, 950, 310, 420, 310, 950))
ventas
fecha comercial zona producto unidades precio
1 2026-01-12 Ana Gil Norte Portátil 2 950
2 2026-01-25 Luis Pardo Sur Móvil 5 420
3 2026-02-03 Ana Gil Norte Móvil 3 420
4 2026-02-18 Marta Ruiz Sur Portátil 1 950
5 2026-03-04 Luis Pardo Sur Tablet 4 310
6 2026-03-15 Marta Ruiz Norte Móvil 6 420
7 2026-03-27 Ana Gil Norte Tablet 2 310
8 2026-04-08 Luis Pardo Sur Portátil 3 950
Una fórmula arrastrada: columnas nuevas
En Excel escribirías =E2*F2 en una columna nueva y la arrastrarías hacia abajo. En R creas la columna en una línea y la operación se aplica a todas las filas:
# Excel: =E2*F2 (arrastrada hacia abajo)
ventas$total <- ventas$unidades * ventas$precio
ventas
fecha comercial zona producto unidades precio total
1 2026-01-12 Ana Gil Norte Portátil 2 950 1900
2 2026-01-25 Luis Pardo Sur Móvil 5 420 2100
3 2026-02-03 Ana Gil Norte Móvil 3 420 1260
4 2026-02-18 Marta Ruiz Sur Portátil 1 950 950
5 2026-03-04 Luis Pardo Sur Tablet 4 310 1240
6 2026-03-15 Marta Ruiz Norte Móvil 6 420 2520
7 2026-03-27 Ana Gil Norte Tablet 2 310 620
8 2026-04-08 Luis Pardo Sur Portátil 3 950 2850
Con dplyr escribirías ventas %>% mutate(total = unidades * precio). Puedes aprender más en el tutorial de mutate.
SI y SI anidados
La función SI (IF) se convierte en ifelse, que evalúa la condición en cada fila y devuelve un valor u otro:
# Excel: =SI(G2>=2000; "Grande"; "Pequeña")
ventas$tipo <- ifelse(ventas$total >= 2000, "Grande", "Pequeña")
ventas[, c("comercial", "total", "tipo")]
comercial total tipo
1 Ana Gil 1900 Pequeña
2 Luis Pardo 2100 Grande
3 Ana Gil 1260 Pequeña
4 Marta Ruiz 950 Pequeña
5 Luis Pardo 1240 Pequeña
6 Marta Ruiz 2520 Grande
7 Ana Gil 620 Pequeña
8 Luis Pardo 2850 Grande
Con varias condiciones (SI anidados o SI.CONJUNTO), anidar ifelse se vuelve ilegible enseguida. case_when de dplyr evalúa las condiciones en orden y asigna el valor de la primera que se cumple, exactamente como SI.CONJUNTO (IFS):
library(dplyr)
# Excel: =SI.CONJUNTO(G2>=2500; "Grande"; G2>=1000; "Mediana"; VERDADERO; "Pequeña")
ventas %>%
mutate(tipo = case_when(total >= 2500 ~ "Grande",
total >= 1000 ~ "Mediana",
.default = "Pequeña")) %>%
select(comercial, total, tipo)
comercial total tipo
1 Ana Gil 1900 Mediana
2 Luis Pardo 2100 Mediana
3 Ana Gil 1260 Mediana
4 Marta Ruiz 950 Pequeña
5 Luis Pardo 1240 Mediana
6 Marta Ruiz 2520 Grande
7 Ana Gil 620 Pequeña
8 Luis Pardo 2850 Grande
SUMAR.SI, CONTAR.SI y PROMEDIO.SI
El truco para traducir las funciones condicionales es que una condición en R devuelve un vector de TRUE y FALSE. Puedes usarlo para seleccionar los valores que la cumplen o sumarlo directamente, porque TRUE cuenta como 1:
# SUMAR.SI (SUMIF): =SUMAR.SI(C:C; "Norte"; G:G)
sum(ventas$total[ventas$zona == "Norte"])
# CONTAR.SI (COUNTIF): =CONTAR.SI(C:C; "Norte")
sum(ventas$zona == "Norte")
# PROMEDIO.SI (AVERAGEIF): =PROMEDIO.SI(C:C; "Norte"; G:G)
mean(ventas$total[ventas$zona == "Norte"])
# SUMAR.SI.CONJUNTO (SUMIFS): =SUMAR.SI.CONJUNTO(G:G; C:C; "Norte"; D:D; "Móvil")
sum(ventas$total[ventas$zona == "Norte" & ventas$producto == "Móvil"])
[1] 6300
[1] 4
[1] 1575
[1] 3780
En Excel lo habitual es escribir un SUMAR.SI para cada zona. En R es más natural calcular el resultado para todos los grupos a la vez con group_by y summarise:
ventas %>%
group_by(zona) %>%
summarise(pedidos = n(),
ventas = sum(total),
media = mean(total))
# A tibble: 2 × 4
zona pedidos ventas media
<chr> <int> <dbl> <dbl>
1 Norte 4 6300 1575
2 Sur 4 7140 1785
Tienes más condiciones (texto que contiene una palabra, fechas, criterios de “mayor que”…) en CONTAR.SI y SUMAR.SI en R.
BUSCARV
Imagina que tienes una segunda tabla con el responsable de cada zona y quieres añadirlo a la tabla de ventas. El BUSCARV (VLOOKUP) de Excel se hace en R con match, que devuelve la fila de la tabla de búsqueda donde se encuentra cada valor:
responsables <- data.frame(zona = c("Norte", "Sur"),
responsable = c("Elena Sanz", "Jorge Vidal"))
# Excel: =BUSCARV(C2; Responsables!A:B; 2; FALSO)
ventas$responsable <- responsables$responsable[match(ventas$zona, responsables$zona)]
ventas[, c("comercial", "zona", "responsable")]
comercial zona responsable
1 Ana Gil Norte Elena Sanz
2 Luis Pardo Sur Jorge Vidal
3 Ana Gil Norte Elena Sanz
4 Marta Ruiz Sur Jorge Vidal
5 Luis Pardo Sur Jorge Vidal
6 Marta Ruiz Norte Elena Sanz
7 Ana Gil Norte Elena Sanz
8 Luis Pardo Sur Jorge Vidal
La alternativa con dplyr es left_join(ventas, responsables, by = "zona"). Los valores no encontrados, las claves duplicadas, la coincidencia aproximada e INDICE COINCIDIR se explican en detalle en cómo hacer un BUSCARV en R.
Tabla dinámica
Una tabla dinámica con las zonas en las filas, los productos en las columnas y la suma de las ventas en los valores es una sola línea de R base con tapply:
tapply(ventas$total, list(ventas$zona, ventas$producto), sum)
Móvil Portátil Tablet
Norte 3780 1900 620
Sur 2100 3800 1240
Con dplyr primero resumes los datos por zona y producto y después repartes los productos en columnas con pivot_wider de tidyr. El argumento values_fill = 0 escribe un 0 en las combinaciones sin ventas, que en Excel serían celdas vacías:
library(tidyr)
ventas %>%
group_by(zona, producto) %>%
summarise(total = sum(total), .groups = "drop") %>%
pivot_wider(names_from = producto, values_from = total, values_fill = 0)
# A tibble: 2 × 4
zona Móvil Portátil Tablet
<chr> <dbl> <dbl> <dbl>
1 Norte 3780 1900 620
2 Sur 2100 3800 1240
El resultado es un data frame normal que puedes seguir transformando o exportar a Excel. Los totales, porcentajes, varios valores y filtros los tienes en tablas dinámicas en R.
Funciones de texto: IZQUIERDA, MAYUSC, CONCATENAR y texto en columnas
Las funciones de texto de Excel tienen su equivalente en R base. Todas ellas trabajan sobre la columna completa a la vez:
# IZQUIERDA (LEFT): =IZQUIERDA(B2; 3)
substr(ventas$comercial, 1, 3)
# MAYUSC (UPPER): =MAYUSC(C2)
toupper(ventas$zona)
# CONCATENAR (CONCATENATE): =B2 & " - " & C2
paste(ventas$comercial, ventas$zona, sep = " - ")
[1] "Ana" "Lui" "Ana" "Mar" "Lui" "Mar" "Ana" "Lui"
[1] "NORTE" "SUR" "NORTE" "SUR" "SUR" "NORTE" "NORTE" "SUR"
[1] "Ana Gil - Norte" "Luis Pardo - Sur" "Ana Gil - Norte"
[4] "Marta Ruiz - Sur" "Luis Pardo - Sur" "Marta Ruiz - Norte"
[7] "Ana Gil - Norte" "Luis Pardo - Sur"
El asistente Texto en columnas de Excel se hace con separate_wider_delim de tidyr, que divide una columna en varias usando un delimitador:
ventas %>%
separate_wider_delim(comercial, delim = " ", names = c("nombre", "apellido")) %>%
select(nombre, apellido) %>%
head(3)
# A tibble: 3 × 2
nombre apellido
<chr> <chr>
1 Ana Gil
2 Luis Pardo
3 Ana Gil
Si algunas filas tienen más o menos partes de las esperadas (un segundo apellido, por ejemplo), consulta texto en columnas en R.
Fechas: HOY y diferencias entre fechas
En Excel una fecha es un número con formato de fecha. En R es un objeto de clase Date, y la diferencia entre dos fechas devuelve el número de días, igual que cuando restas dos fechas en Excel. Sys.Date() es el equivalente de HOY() (TODAY()), pero aquí usamos una fecha fija para que obtengas el mismo resultado:
# Días desde cada venta: =FECHA(2026;10;31) - A2
ventas$dias <- as.numeric(as.Date("2026-10-31") - ventas$fecha)
# Año y mes: =TEXTO(A2; "aaaa-mm")
ventas$mes <- format(ventas$fecha, "%Y-%m")
ventas[1:4, c("fecha", "dias", "mes")]
fecha dias mes
1 2026-01-12 292 2026-01
2 2026-01-25 279 2026-01
3 2026-02-03 270 2026-02
4 2026-02-18 255 2026-02
Aprende a convertir texto en fechas, extraer el día de la semana o sumar meses en el tutorial sobre fechas en R.
Leer y guardar archivos de Excel
No necesitas convertir tus libros de Excel a CSV para usarlos en R. El paquete readxl lee archivos .xlsx y .xls y el paquete writexl los escribe. Ninguno de los dos necesita tener Excel ni Java instalados. En este ejemplo guardamos la tabla de ventas y la volvemos a leer:
# install.packages(c("readxl", "writexl"))
library(readxl)
library(writexl)
# Guardar el data frame como archivo de Excel
write_xlsx(ventas[, 1:7], "ventas.xlsx")
# Leer el archivo de Excel
df <- read_excel("ventas.xlsx")
df
# A tibble: 8 × 7
fecha comercial zona producto unidades precio total
<dttm> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 2026-01-12 00:00:00 Ana Gil Norte Portátil 2 950 1900
2 2026-01-25 00:00:00 Luis Pardo Sur Móvil 5 420 2100
3 2026-02-03 00:00:00 Ana Gil Norte Móvil 3 420 1260
4 2026-02-18 00:00:00 Marta Ruiz Sur Portátil 1 950 950
5 2026-03-04 00:00:00 Luis Pardo Sur Tablet 4 310 1240
6 2026-03-15 00:00:00 Marta Ruiz Norte Móvil 6 420 2520
7 2026-03-27 00:00:00 Ana Gil Norte Tablet 2 310 620
8 2026-04-08 00:00:00 Luis Pardo Sur Portátil 3 950 2850
Fíjate en que las fechas vuelven como fecha y hora (<dttm>), porque así es como las guarda Excel. Usa as.Date(df$fecha) si solo necesitas la fecha. Otros argumentos útiles de read_excel son:
sheet: el nombre o el número de la hoja que quieres leer, por ejemplosheet = "2026".excel_sheets("archivo.xlsx")lista las hojas de un libro.range: un rango en notación de Excel, comorange = "B3:H50", cuando la tabla no empieza enA1.skip: el número de filas que hay que saltar al principio (títulos, logos, notas…).na: los valores que se leerán comoNA, por ejemplona = c("", "-", "n/d").
Para escribir varias hojas en el mismo libro, pasa a write_xlsx una lista con nombres de data frames: write_xlsx(list(Ventas = ventas, Resumen = resumen), "informe.xlsx"). Tienes todas las opciones, incluidos otros paquetes como openxlsx, en los tutoriales sobre cómo leer archivos de Excel en R y cómo exportar datos desde R.
Consejos para usuarios de Excel
La mayoría de problemas de quien pasa de Excel a R vienen de cómo están construidas las hojas de cálculo, no de R. Estos consejos te ahorrarán mucho tiempo:
- Una sola fila de encabezado. La primera fila de la tabla debe contener los nombres de las columnas, y nada más. Los títulos encima de la tabla, los encabezados de dos filas o las notas al final hay que quitarlos o saltarlos con
skipyrange. - Nada de celdas combinadas. Al leer una celda combinada, solo la primera celda tiene el valor y el resto son
NA. Rellena el valor en todas las filas. - Datos ordenados (tidy data): cada columna es una variable, cada fila una observación y cada celda un único valor. Una hoja con una columna por mes (
Ene,Feb,Mar…) es fácil de leer pero difícil de analizar. Conviértela en una tabla larga con pivot_longer. - Un solo tipo de dato por columna. Una columna con números y algunas celdas con texto como
"N/D"o"pendiente"se lee como texto. Entoncessumfalla y las comparaciones no funcionan como esperas. - No uses colores como datos. R no puede ver que una fila está resaltada en amarillo. Si el color significa algo (“pago pendiente”), crea una columna con esa información.
- No toques los datos originales. Lee el archivo original, haz todas las transformaciones en el script y guarda el resultado en un archivo nuevo. Si algo sale mal, vuelve a ejecutar el script.
Por qué un script es mejor que los clics: un script es un registro de todos los pasos que has dado. Si el mes que viene recibes un archivo nuevo, solo tienes que cambiar el nombre del archivo y volver a ejecutarlo. Si alguien te pregunta cómo se ha calculado un número, la respuesta está en el código. Y si te equivocas, corriges una línea en lugar de repetir todos los clics.
Por último, ten en cuenta que algunas funciones con el mismo nombre no dan exactamente el mismo resultado en Excel y en R:
round: Excel redondea los valores que terminan en 5 alejándose de cero (REDONDEAR(2,5; 0)es 3), pero R sigue el estándar IEC 60559 y los redondea al número par:round(c(0.5, 1.5, 2.5, 3.5))devuelve0 2 2 4.REDONDEAR.MASyREDONDEAR.MENOS(ROUNDUPyROUNDDOWN) redondean alejándose de cero y hacia cero.truncequivale aREDONDEAR.MENOS, peroceilingsiempre redondea hacia arriba:ceiling(-2.1)es-2, mientras queREDONDEAR.MAS(-2,1; 0)es-3.DESVESTysdcalculan la desviación típica muestral. Si usabasDESVEST.P(poblacional), el resultado será distinto.- Decimales: Excel en español usa la coma como separador decimal, pero en R el separador decimal es siempre el punto (
2.5, no2,5). - Búsquedas:
BUSCARVno distingue entre mayúsculas y minúsculas, peromatchy los joins sí, como se explica en el tutorial de BUSCARV.