El comando de filtro se utiliza para eliminar filas (registros) que no desea.
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.5 ✓ purrr 0.3.4
## ✓ tibble 3.1.5 ✓ dplyr 1.0.7
## ✓ tidyr 1.1.4 ✓ stringr 1.4.0
## ✓ readr 2.0.2 ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
data("ChickWeight")
# Selecciona solo los datos de los pollos con 21 días
(twe_chi <- filter(ChickWeight, Time==21))
## weight Time Chick Diet
## 1 205 21 1 1
## 2 215 21 2 1
## 3 202 21 3 1
## 4 157 21 4 1
## 5 223 21 5 1
## 6 157 21 6 1
## 7 305 21 7 1
## 8 98 21 9 1
## 9 124 21 10 1
## 10 175 21 11 1
## 11 205 21 12 1
## 12 96 21 13 1
## 13 266 21 14 1
## 14 142 21 17 1
## 15 157 21 19 1
## 16 117 21 20 1
## 17 331 21 21 2
## 18 167 21 22 2
## 19 175 21 23 2
## 20 74 21 24 2
## 21 265 21 25 2
## 22 251 21 26 2
## 23 192 21 27 2
## 24 233 21 28 2
## 25 309 21 29 2
## 26 150 21 30 2
## 27 256 21 31 3
## 28 305 21 32 3
## 29 147 21 33 3
## 30 341 21 34 3
## 31 373 21 35 3
## 32 220 21 36 3
## 33 178 21 37 3
## 34 290 21 38 3
## 35 272 21 39 3
## 36 321 21 40 3
## 37 204 21 41 4
## 38 281 21 42 4
## 39 200 21 43 4
## 40 196 21 45 4
## 41 238 21 46 4
## 42 205 21 47 4
## 43 322 21 48 4
## 44 237 21 49 4
## 45 264 21 50 4
NOTA: En el comando de filtro, “igual” se representa con doble igual“==”.
Se filtro el conjunto de datos ChickWeight con pollos de 21 días de edad y un peso superior a 121
(twe_chi_wei <- filter(ChickWeight, Time==21, weight>121))
## weight Time Chick Diet
## 1 205 21 1 1
## 2 215 21 2 1
## 3 202 21 3 1
## 4 157 21 4 1
## 5 223 21 5 1
## 6 157 21 6 1
## 7 305 21 7 1
## 8 124 21 10 1
## 9 175 21 11 1
## 10 205 21 12 1
## 11 266 21 14 1
## 12 142 21 17 1
## 13 157 21 19 1
## 14 331 21 21 2
## 15 167 21 22 2
## 16 175 21 23 2
## 17 265 21 25 2
## 18 251 21 26 2
## 19 192 21 27 2
## 20 233 21 28 2
## 21 309 21 29 2
## 22 150 21 30 2
## 23 256 21 31 3
## 24 305 21 32 3
## 25 147 21 33 3
## 26 341 21 34 3
## 27 373 21 35 3
## 28 220 21 36 3
## 29 178 21 37 3
## 30 290 21 38 3
## 31 272 21 39 3
## 32 321 21 40 3
## 33 204 21 41 4
## 34 281 21 42 4
## 35 200 21 43 4
## 36 196 21 45 4
## 37 238 21 46 4
## 38 205 21 47 4
## 39 322 21 48 4
## 40 237 21 49 4
## 41 264 21 50 4
Se puede utilizar tantos símbolos OR (“|”) como sea necesario.
Filtro basado en el operador lógico OR:
(diet_twe_wei<- filter(ChickWeight, Diet== 2|Time==21))
## weight Time Chick Diet
## 1 205 21 1 1
## 2 215 21 2 1
## 3 202 21 3 1
## 4 157 21 4 1
## 5 223 21 5 1
## 6 157 21 6 1
## 7 305 21 7 1
## 8 98 21 9 1
## 9 124 21 10 1
## 10 175 21 11 1
## 11 205 21 12 1
## 12 96 21 13 1
## 13 266 21 14 1
## 14 142 21 17 1
## 15 157 21 19 1
## 16 117 21 20 1
## 17 40 0 21 2
## 18 50 2 21 2
## 19 62 4 21 2
## 20 86 6 21 2
## 21 125 8 21 2
## 22 163 10 21 2
## 23 217 12 21 2
## 24 240 14 21 2
## 25 275 16 21 2
## 26 307 18 21 2
## 27 318 20 21 2
## 28 331 21 21 2
## 29 41 0 22 2
## 30 55 2 22 2
## 31 64 4 22 2
## 32 77 6 22 2
## 33 90 8 22 2
## 34 95 10 22 2
## 35 108 12 22 2
## 36 111 14 22 2
## 37 131 16 22 2
## 38 148 18 22 2
## 39 164 20 22 2
## 40 167 21 22 2
## 41 43 0 23 2
## 42 52 2 23 2
## 43 61 4 23 2
## 44 73 6 23 2
## 45 90 8 23 2
## 46 103 10 23 2
## 47 127 12 23 2
## 48 135 14 23 2
## 49 145 16 23 2
## 50 163 18 23 2
## 51 170 20 23 2
## 52 175 21 23 2
## 53 42 0 24 2
## 54 52 2 24 2
## 55 58 4 24 2
## 56 74 6 24 2
## 57 66 8 24 2
## 58 68 10 24 2
## 59 70 12 24 2
## 60 71 14 24 2
## 61 72 16 24 2
## 62 72 18 24 2
## 63 76 20 24 2
## 64 74 21 24 2
## 65 40 0 25 2
## 66 49 2 25 2
## 67 62 4 25 2
## 68 78 6 25 2
## 69 102 8 25 2
## 70 124 10 25 2
## 71 146 12 25 2
## 72 164 14 25 2
## 73 197 16 25 2
## 74 231 18 25 2
## 75 259 20 25 2
## 76 265 21 25 2
## 77 42 0 26 2
## 78 48 2 26 2
## 79 57 4 26 2
## 80 74 6 26 2
## 81 93 8 26 2
## 82 114 10 26 2
## 83 136 12 26 2
## 84 147 14 26 2
## 85 169 16 26 2
## 86 205 18 26 2
## 87 236 20 26 2
## 88 251 21 26 2
## 89 39 0 27 2
## 90 46 2 27 2
## 91 58 4 27 2
## 92 73 6 27 2
## 93 87 8 27 2
## 94 100 10 27 2
## 95 115 12 27 2
## 96 123 14 27 2
## 97 144 16 27 2
## 98 163 18 27 2
## 99 185 20 27 2
## 100 192 21 27 2
## 101 39 0 28 2
## 102 46 2 28 2
## 103 58 4 28 2
## 104 73 6 28 2
## 105 92 8 28 2
## 106 114 10 28 2
## 107 145 12 28 2
## 108 156 14 28 2
## 109 184 16 28 2
## 110 207 18 28 2
## 111 212 20 28 2
## 112 233 21 28 2
## 113 39 0 29 2
## 114 48 2 29 2
## 115 59 4 29 2
## 116 74 6 29 2
## 117 87 8 29 2
## 118 106 10 29 2
## 119 134 12 29 2
## 120 150 14 29 2
## 121 187 16 29 2
## 122 230 18 29 2
## 123 279 20 29 2
## 124 309 21 29 2
## 125 42 0 30 2
## 126 48 2 30 2
## 127 59 4 30 2
## 128 72 6 30 2
## 129 85 8 30 2
## 130 98 10 30 2
## 131 115 12 30 2
## 132 122 14 30 2
## 133 143 16 30 2
## 134 151 18 30 2
## 135 157 20 30 2
## 136 150 21 30 2
## 137 256 21 31 3
## 138 305 21 32 3
## 139 147 21 33 3
## 140 341 21 34 3
## 141 373 21 35 3
## 142 220 21 36 3
## 143 178 21 37 3
## 144 290 21 38 3
## 145 272 21 39 3
## 146 321 21 40 3
## 147 204 21 41 4
## 148 281 21 42 4
## 149 200 21 43 4
## 150 196 21 45 4
## 151 238 21 46 4
## 152 205 21 47 4
## 153 322 21 48 4
## 154 237 21 49 4
## 155 264 21 50 4
(smallest_wei <- filter(ChickWeight, weight==min(weight)))
## weight Time Chick Diet
## 1 35 2 18 1
En la salida del codigo se ve una sola fila con lo9s datos del menor peso de obtenido por los pollos
Filtrar con condiciones separadas por comas:
(chick.subset <- filter(ChickWeight, Time < 3, weight > 53))
## weight Time Chick Diet
## 1 55 2 22 2
## 2 55 2 40 3
## 3 55 2 43 4
## 4 54 2 50 4
El conjunto de datos airquality presenta un valor faltan (NA) en la columna uno (Ozone)
Antes de filtrar los datos
data("airquality")
head(airquality,10)
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 NA NA 14.3 56 5 5
## 6 28 NA 14.9 66 5 6
## 7 23 299 8.6 65 5 7
## 8 19 99 13.8 59 5 8
## 9 8 19 20.1 61 5 9
## 10 NA 194 8.6 69 5 10
Después de filtrar los datos
no.ozone = filter(airquality, !is.na(Ozone))
head(no.ozone,8)
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 28 NA 14.9 66 5 6
## 6 23 299 8.6 65 5 7
## 7 19 99 13.8 59 5 8
## 8 8 19 20.1 61 5 9
NOTA: Se elimino la fila que presentaba el NA en la columna de OZONE pero aun se encuentra el NA en la columna de Solar.R
Se usa complete.cases() para eliminar cualquier fila que contenga un NA en cualquier columna
(no_na <- filter(airquality[1:10,], complete.cases(airquality[1:10,])))
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 23 299 8.6 65 5 7
## 6 19 99 13.8 59 5 8
## 7 8 19 20.1 61 5 9
“%in%” es un operador que permite una forma abreviada para incluir o excluir valores especificados de una base de datos
data("iris")
table(iris$Species) #recuento de especies en el conjunto de datos, antes del filtrado
##
## setosa versicolor virginica
## 50 50 50
dos_especies <- filter(iris,Species %in% c("setosa", "virginica"))
table(dos_especies$Species) #recuento de especies en el conjunto de datos, despues del filtrado
##
## setosa versicolor virginica
## 50 0 50
Número de filas antes y despues del filtrado
nrow(iris); nrow(dos_especies)
## [1] 150
## [1] 100
data("airquality")
tres_columnas <- filter(airquality, Ozone > 29)[,1:3] #primero van las filas y luego las columnas
head(tres_columnas)
## Ozone Solar.R Wind
## 1 41 190 7.4
## 2 36 118 8.0
## 3 34 307 12.0
## 4 30 322 11.5
## 5 32 92 12.0
## 6 45 252 14.9
group_by() permite el recuento de filas en función del número de engranajes. En la siguiente primera tabla, hay 15 registros con un automóvil que tiene tres marchas, 12 registros para cuatro marchas y cinco registros para cinco marchas.
table(mtcars$gear)
##
## 3 4 5
## 15 12 5
Después de aplicar el filtro y crear un nuevo marco de datos, no hay registros que tengan cinco engranajes:
engranaje <- mtcars %>%
group_by(gear) %>%
filter(n() > 10) #Una vez realizados los recuentos de engranajes, solo se incluyen en la salida aquellas filas cuyo recuento total supere los diez.
table(engranaje$gear) #Todo lo que desea ver aquí son registros que tienen al menos 11 filas con un número específico de marchas en el automóvil.
##
## 3 4
## 15 12
Se pueden agregar criterios adicionales al filtro :
potencia_motor<- mtcars %>%
group_by(gear) %>%
filter(n() > 10, hp < 105)#se incluye el requisito de que la potencia sea inferior a 105
table(potencia_motor$gear)
##
## 3 4
## 1 7
Se seleccionan las columnas con nombres que inicien con S
names(iris)#muestra los nombres de las columnas
## [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
nombres_datos <- iris%>% dplyr::select(starts_with("S"))
head(nombres_datos)#Se utiliza head() para reducir el número de filas que se muestran en la salida del codigo
## Sepal.Length Sepal.Width Species
## 1 5.1 3.5 setosa
## 2 4.9 3.0 setosa
## 3 4.7 3.2 setosa
## 4 4.6 3.1 setosa
## 5 5.0 3.6 setosa
## 6 5.4 3.9 setosa
Se utiliza filter_at () para buscar filas que cumplan con algunos criterios al pasar por el filtro de datos.
(new.mt <- mtcars %>% filter_at(vars(cyl, hp),
all_vars(. == max(.))))
## mpg cyl disp hp drat wt qsec vs am gear carb
## Maserati Bora 15 8 301 335 3.54 3.57 14.6 0 1 5 8
Otro ejemplo que puede verse es con la base de datos de Suzan Baert:
(msleep<-ggplot2::msleep)
## # A tibble: 83 × 11
## name genus vore order conservation sleep_total sleep_rem sleep_cycle awake
## <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Cheet… Acin… carni Carn… lc 12.1 NA NA 11.9
## 2 Owl m… Aotus omni Prim… <NA> 17 1.8 NA 7
## 3 Mount… Aplo… herbi Rode… nt 14.4 2.4 NA 9.6
## 4 Great… Blar… omni Sori… lc 14.9 2.3 0.133 9.1
## 5 Cow Bos herbi Arti… domesticated 4 0.7 0.667 20
## 6 Three… Brad… herbi Pilo… <NA> 14.4 2.2 0.767 9.6
## 7 North… Call… carni Carn… vu 8.7 1.4 0.383 15.3
## 8 Vespe… Calo… <NA> Rode… <NA> 7 NA NA 17
## 9 Dog Canis carni Carn… domesticated 10.1 2.9 0.333 13.9
## 10 Roe d… Capr… herbi Arti… lc 3 NA NA 21
## # … with 73 more rows, and 2 more variables: brainwt <dbl>, bodywt <dbl>
(msleep.over.5 <- msleep %>%
select(name, sleep_total:sleep_rem, brainwt:bodywt) %>%
filter_at(vars(contains("sleep")), #La función filter_at dice que mire solo las variables que contienen la palabra "sleep".
all_vars(.>5))) #El "." significa cualquier variable con dormir en el nombre.
## # A tibble: 2 × 5
## name sleep_total sleep_rem brainwt bodywt
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Thick-tailed opposum 19.4 6.6 NA 0.37
## 2 Giant armadillo 18.1 6.1 0.081 60
La función arrange() reordena un vector o un dataframe en una secuencia definida que puede ser ascendente o descendente.
msleep<-ggplot2::msleep
msleep[,1:4]
## # A tibble: 83 × 4
## name genus vore order
## <chr> <chr> <chr> <chr>
## 1 Cheetah Acinonyx carni Carnivora
## 2 Owl monkey Aotus omni Primates
## 3 Mountain beaver Aplodontia herbi Rodentia
## 4 Greater short-tailed shrew Blarina omni Soricomorpha
## 5 Cow Bos herbi Artiodactyla
## 6 Three-toed sloth Bradypus herbi Pilosa
## 7 Northern fur seal Callorhinus carni Carnivora
## 8 Vesper mouse Calomys <NA> Rodentia
## 9 Dog Canis carni Carnivora
## 10 Roe deer Capreolus herbi Artiodactyla
## # … with 73 more rows
animal1<- arrange(msleep, vore, order)
animal1[,1:4]
## # A tibble: 83 × 4
## name genus vore order
## <chr> <chr> <chr> <chr>
## 1 Cheetah Acinonyx carni Carnivora
## 2 Northern fur seal Callorhinus carni Carnivora
## 3 Dog Canis carni Carnivora
## 4 Domestic cat Felis carni Carnivora
## 5 Gray seal Haliochoerus carni Carnivora
## 6 Tiger Panthera carni Carnivora
## 7 Jaguar Panthera carni Carnivora
## 8 Lion Panthera carni Carnivora
## 9 Caspian seal Phoca carni Carnivora
## 10 Genet Genetta carni Carnivora
## # … with 73 more rows
animal2 <- arrange(msleep, vore, desc(order))
head(animal2[,1:4])
## # A tibble: 6 × 4
## name genus vore order
## <chr> <chr> <chr> <chr>
## 1 Northern grasshopper mouse Onychomys carni Rodentia
## 2 Slow loris Nyctibeus carni Primates
## 3 Thick-tailed opposum Lutreolina carni Didelphimorphia
## 4 Long-nosed armadillo Dasypus carni Cingulata
## 5 Pilot whale Globicephalus carni Cetacea
## 6 Common porpoise Phocoena carni Cetacea
rename() permite cambiar el nombre de una o más columnas. Es una función de conveniencia y no cambia datos.
names(iris)
## [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
Muestra los nuevos nombres de las columnas
iris_renombre <- rename(iris, width.of.petals = Petal.Width,
various.plants.and.animals = Species)
names(iris_renombre)
## [1] "Sepal.Length" "Sepal.Width"
## [3] "Petal.Length" "width.of.petals"
## [5] "various.plants.and.animals"
mutate() agrega nuevas variables a un marco de datos.
Chickweight.with.log <- mutate(ChickWeight, #Requiere el marco de datos original como primer argumento
log.of.weight = log10(weight))#luego los argumentos para crear nuevas variables como los argumentos restantes.
Chickweight.with.log[1:2,]
## weight Time Chick Diet log.of.weight
## 1 42 0 1 1 1.623249
## 2 51 2 1 1 1.707570
msleep <- ggplot2::msleep #marco de datos msleep del paquete ggplot2
names(msleep)
## [1] "name" "genus" "vore" "order" "conservation"
## [6] "sleep_total" "sleep_rem" "sleep_cycle" "awake" "brainwt"
## [11] "bodywt"
raiz_msleep<- mutate_all(msleep[,6:11], #cada una de las columnas designadas (6–11) proporciona números a la función de raíz cuadrada
funs("square root" = sqrt( . ))) #nueva columna con el sufijo square root
## Warning: `funs()` was deprecated in dplyr 0.8.0.
## Please use a list of either functions or lambdas:
##
## # Simple named list:
## list(mean = mean, median = median)
##
## # Auto named with `tibble::lst()`:
## tibble::lst(mean, median)
##
## # Using lambdas
## list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
names(raiz_msleep)
## [1] "sleep_total" "sleep_rem"
## [3] "sleep_cycle" "awake"
## [5] "brainwt" "bodywt"
## [7] "sleep_total_square root" "sleep_rem_square root"
## [9] "sleep_cycle_square root" "awake_square root"
## [11] "brainwt_square root" "bodywt_square root"
raiz_msleep
## # A tibble: 83 × 12
## sleep_total sleep_rem sleep_cycle awake brainwt bodywt `sleep_total_square…
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 12.1 NA NA 11.9 NA 50 3.48
## 2 17 1.8 NA 7 0.0155 0.48 4.12
## 3 14.4 2.4 NA 9.6 NA 1.35 3.79
## 4 14.9 2.3 0.133 9.1 0.00029 0.019 3.86
## 5 4 0.7 0.667 20 0.423 600 2
## 6 14.4 2.2 0.767 9.6 NA 3.85 3.79
## 7 8.7 1.4 0.383 15.3 NA 20.5 2.95
## 8 7 NA NA 17 NA 0.045 2.65
## 9 10.1 2.9 0.333 13.9 0.07 14 3.18
## 10 3 NA NA 21 0.0982 14.8 1.73
## # … with 73 more rows, and 5 more variables: sleep_rem_square root <dbl>,
## # sleep_cycle_square root <dbl>, awake_square root <dbl>,
## # brainwt_square root <dbl>, bodywt_square root <dbl>
data("Titanic") #Se utiliza el conjunto de datos Titanic
Titanic <- as.data.frame(Titanic) #as.data.frame() se usa para convertir a un marco de datos
head(Titanic)
## Class Sex Age Survived Freq
## 1 1st Male Child No 0
## 2 2nd Male Child No 0
## 3 3rd Male Child No 35
## 4 Crew Male Child No 0
## 5 1st Female Child No 0
## 6 2nd Female Child No 0
clasificacion_titanic <- mutate_at(Titanic, vars(Class,Age,Survived), #las variables con rangos de datos se crean con mutate_at()
funs(Rank = min_rank(desc(.))))
head(clasificacion_titanic)
## Class Sex Age Survived Freq Class_Rank Age_Rank Survived_Rank
## 1 1st Male Child No 0 25 17 17
## 2 2nd Male Child No 0 17 17 17
## 3 3rd Male Child No 35 9 17 17
## 4 Crew Male Child No 0 1 17 17
## 5 1st Female Child No 0 25 17 17
## 6 2nd Female Child No 0 17 17 17
La función mutate_if() combina el operador lógico if y mutate() para crear una nueva variable o alterar una ya existente.
EJEMPLO 1
div10 <- function (a.number) (a.number / 10) #funcion para dividir un numero en 10
head(CO2) #Se utiliza el conjunto de datos CO2
## Plant Type Treatment conc uptake
## 1 Qn1 Quebec nonchilled 95 16.0
## 2 Qn1 Quebec nonchilled 175 30.4
## 3 Qn1 Quebec nonchilled 250 34.8
## 4 Qn1 Quebec nonchilled 350 37.2
## 5 Qn1 Quebec nonchilled 500 35.3
## 6 Qn1 Quebec nonchilled 675 39.2
new.df <- CO2 %>%
mutate_if(is.numeric, div10) #Ahora se divide cualquier columna que tenga un formato numérico por 10, utilizando la función creada anteriormente, div10
head(new.df)
## Plant Type Treatment conc uptake
## 1 Qn1 Quebec nonchilled 9.5 1.60
## 2 Qn1 Quebec nonchilled 17.5 3.04
## 3 Qn1 Quebec nonchilled 25.0 3.48
## 4 Qn1 Quebec nonchilled 35.0 3.72
## 5 Qn1 Quebec nonchilled 50.0 3.53
## 6 Qn1 Quebec nonchilled 67.5 3.92
EJEMPLO 2
(df <- data.frame(
alpha = c(22, 1, NA),
almond = c(0, 5, 10),
grape = c(0, 2, 2),
apple = c(NA, 5, 10)))
## alpha almond grape apple
## 1 22 0 0 NA
## 2 1 5 2 5
## 3 NA 10 2 10
(df.sin.NA <- df %>% mutate_if(is.numeric, #Cualquier NA en un campo numérico se reemplaza por cero
coalesce, ... = 0)) #“Coalesce” es una función que encuentra el primer valor presente después de un NA.
## alpha almond grape apple
## 1 22 0 0 0
## 2 1 5 2 5
## 3 0 10 2 10
Todas las columnas con los caracteres sleep en el nombre de la columna serán convertidos a caracter.
msleep<-ggplot2::msleep
table(msleep$vore)
##
## carni herbi insecti omni
## 19 32 5 20
msleep.no.c.or.a <- filter(msleep, !str_detect(vore,
paste(c("c","a"), collapse = "|")))
table(msleep.no.c.or.a$vore)
##
## herbi omni
## 32 20
msleep.doble.ind <- mutate(msleep, duplicate.indicator =
duplicated(conservation)) #Se agrego un campo que indique si un valor particular en una columna ocurre más de una vez. En este caso, la columna es conservation
msleep.doble.ind[1:6,]
## # A tibble: 6 × 12
## name genus vore order conservation sleep_total sleep_rem sleep_cycle awake
## <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Cheetah Acin… carni Carn… lc 12.1 NA NA 11.9
## 2 Owl mo… Aotus omni Prim… <NA> 17 1.8 NA 7
## 3 Mounta… Aplo… herbi Rode… nt 14.4 2.4 NA 9.6
## 4 Greate… Blar… omni Sori… lc 14.9 2.3 0.133 9.1
## 5 Cow Bos herbi Arti… domesticated 4 0.7 0.667 20
## 6 Three-… Brad… herbi Pilo… <NA> 14.4 2.2 0.767 9.6
## # … with 3 more variables: brainwt <dbl>, bodywt <dbl>,
## # duplicate.indicator <lgl>
Otra forma de escribir lo anterior es:
(msleep.doble.ind2 <- mutate(msleep,
duplicate.indicator = duplicated(conservation, genus)) %>%
arrange(conservation,genus))
## # A tibble: 83 × 12
## name genus vore order conservation sleep_total sleep_rem sleep_cycle awake
## <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Giraf… Gira… herbi Arti… cd 1.9 0.4 NA 22.1
## 2 Pilot… Glob… carni Ceta… cd 2.7 0.1 NA 21.4
## 3 Cow Bos herbi Arti… domesticated 4 0.7 0.667 20
## 4 Dog Canis carni Carn… domesticated 10.1 2.9 0.333 13.9
## 5 Guine… Cavis herbi Rode… domesticated 9.4 0.8 0.217 14.6
## 6 Chinc… Chin… herbi Rode… domesticated 12.5 1.5 0.117 11.5
## 7 Horse Equus herbi Peri… domesticated 2.9 0.6 1 21.1
## 8 Donkey Equus herbi Peri… domesticated 3.1 0.4 NA 20.9
## 9 Domes… Felis carni Carn… domesticated 12.5 3.2 0.417 11.5
## 10 Rabbit Oryc… herbi Lago… domesticated 8.4 0.9 0.417 15.6
## # … with 73 more rows, and 3 more variables: brainwt <dbl>, bodywt <dbl>,
## # duplicate.indicator <lgl>
NOTA: Tanto conservation y genus deben duplicarse para que duplicate.indicator() se establezca en TRUE.
fruit <- c("apple","pear","orange","grape", "orange","orange")
x <- c(1,2,4,9,4,6)
y <- c(22,3,4,55,15,9)
z <- c(3,1,4,10,12,8)
w <- c(2,2,2,4,5,6)
(fruta<-data.frame(fruit,x,y,z,w)) #Se creo un data frame con nombres de frutas
## fruit x y z w
## 1 apple 1 22 3 2
## 2 pear 2 3 1 2
## 3 orange 4 4 4 2
## 4 grape 9 55 10 4
## 5 orange 4 15 12 5
## 6 orange 6 9 8 6
#Se utilizan las funciones mutate() y duplicate.indicator en el data frame creado anteriormente
(fruta_dup <- mutate(fruta, duplicate.indicator = duplicated(fruit)))
## fruit x y z w duplicate.indicator
## 1 apple 1 22 3 2 FALSE
## 2 pear 2 3 1 2 FALSE
## 3 orange 4 4 4 2 FALSE
## 4 grape 9 55 10 4 FALSE
## 5 orange 4 15 12 5 TRUE
## 6 orange 6 9 8 6 TRUE
NOTA: DPLYR baja por las filas y observa los valores de la columna “fruta”. No puede detectar el primer dato duplicado porque aún no sabe si hay otro. Cuando ve “orange” por segunda y tercera vez, establece la columna duplicate.indicator() como “TRUE” para las filas que contienen el valor “orange”. Si se desea verificar varios campos, se usa mutate() para combinarlos en un nuevo campo antes de usar el indicador lógico duplicado (TRUE / False)
fruit <- c("apple","pear","orange","grape", "orange","orange")
x <- c(1,2,4,9,4,6)
y <- c(22,3,4,55,15,9)
z <- c(3,1,4,10,12,8)
df <- data.frame(fruit,x,y,z)
(df <- mutate(df, z = NULL))
## fruit x y
## 1 apple 1 22
## 2 pear 2 3
## 3 orange 4 4
## 4 grape 9 55
## 5 orange 4 15
## 6 orange 6 9
Forma de usar mutate() dentro de este misma función
NO RECOMENDADO
if (!require("nycflights13")) install.packages("nycflights13")
## Loading required package: nycflights13
mutate(flights,
gain = arr_delay - dep_delay,
hours = air_time / 60,
gain_per_hour = gain / hours,
gain_per_minute = 60 * gain_per_hour)
## # A tibble: 336,776 × 23
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 558 600 -2 753 745
## # … with 336,766 more rows, and 15 more variables: arr_delay <dbl>,
## # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## # air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>,
## # gain <dbl>, hours <dbl>, gain_per_hour <dbl>, gain_per_minute <dbl>
RECOMENDADO
if (!require("nycflights13")) install.packages("nycflights13")
newfield.flights <- flights %>%
mutate(gain = arr_delay - dep_delay,
hours = air_time / 60) %>%
mutate(gain_per_hour = gain / hours) %>%
mutate(gain_per_minute = 60 * gain_per_hour)
newfield.flights[1:6,c(1:2,20:23)] #Muestra las columnas seleccionadas para las primeras seis filas, incluidas las recién creadas.
## # A tibble: 6 × 6
## year month gain hours gain_per_hour gain_per_minute
## <int> <int> <dbl> <dbl> <dbl> <dbl>
## 1 2013 1 9 3.78 2.38 143.
## 2 2013 1 16 3.78 4.23 254.
## 3 2013 1 31 2.67 11.6 698.
## 4 2013 1 -17 3.05 -5.57 -334.
## 5 2013 1 -19 1.93 -9.83 -590.
## 6 2013 1 16 2.5 6.4 384
La función trasmute() permite crear un marco de datos completamente nuevo basado en cálculos realizados en variables existentes.
fruit <- c("apple","pear","orange","grape", "orange","orange")
x <- c(1,2,4,9,4,6)
y <- c(22,3,4,55,15,9)
z <- c(3,1,4,10,12,8)
(fruta1 <- data.frame(fruit,x,y,z)) #Antes de usar trasmute()
## fruit x y z
## 1 apple 1 22 3
## 2 pear 2 3 1
## 3 orange 4 4 4
## 4 grape 9 55 10
## 5 orange 4 15 12
## 6 orange 6 9 8
(df <- transmute(df, new.variable = x + y + z)) #Despues de usar trasmute()
## new.variable
## 1 26
## 2 6
## 3 12
## 4 74
## 5 31
## 6 23
double.it <- function(x) x*2 #función simple para duplicar el valor de un número
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
iris %>%
mutate(across(where(is.numeric), double.it)) %>%
head() #Muestra un nuevo marco de datos de "iris" con valores duplicados para las columnas numéricas
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 10.2 7.0 2.8 0.4 setosa
## 2 9.8 6.0 2.8 0.4 setosa
## 3 9.4 6.4 2.6 0.4 setosa
## 4 9.2 6.2 3.0 0.4 setosa
## 5 10.0 7.2 2.8 0.4 setosa
## 6 10.8 7.8 3.4 0.8 setosa
case_when() puede mutar un nuevo campo y luego establecer valores basados en múltiples condiciones.
row1 <- c("a","b","c","d","e","f","column.to.be.changed")
row2 <- c(1,1,1,6,6,1,2)
row3 <- c(3,4,4,6,4,4,4)
row4 <- c(4,6,25,5,5,2,9)
row5 <- c(5,3,6,3,3,6,2)
df1 <- as.data.frame(rbind(row2,row3,row4,row5))
names(df1) <- row1
df1
## a b c d e f column.to.be.changed
## row2 1 1 1 6 6 1 2
## row3 3 4 4 6 4 4 4
## row4 4 6 25 5 5 2 9
## row5 5 3 6 3 3 6 2
(new.df <-df1 %>%
mutate(columna.cambiada= case_when(a == 2 | a == 5 |
a == 7 | (a == 1 & b == 4) ~ 2, a == 0 | a == 1 | a == 4 |
a == 3 | c == 4 ~ 3, TRUE ~ NA_real_))) #Esta es una serie de condiciones "OR". Si alguno de ellos es "TRUE", entonces la última columna (columna.cambiada) será un 2 o un 3
## a b c d e f column.to.be.changed columna.cambiada
## row2 1 1 1 6 6 1 2 3
## row3 3 4 4 6 4 4 4 3
## row4 4 6 25 5 5 2 9 3
## row5 5 3 6 3 3 6 2 2
select() conserva solo las variables que incluye dentro de esta declaración. La función rename, comunmente mencionada como una función hermana de select(), no elimina ninguna variable. ### 1.5.1 Eliminar una columna
fruta1 #Antes de utilizar select()
## fruit x y z
## 1 apple 1 22 3
## 2 pear 2 3 1
## 3 orange 4 4 4
## 4 grape 9 55 10
## 5 orange 4 15 12
## 6 orange 6 9 8
(no.fruit <- dplyr::select(fruta1, -fruit))#Se coloca un signo menos delante de cualquier variable que se desee eliminar. La columna con los nombres de frutas no se incluye en el nuevo marco de datos.
## x y z
## 1 1 22 3
## 2 2 3 1
## 3 4 4 4
## 4 9 55 10
## 5 4 15 12
## 6 6 9 8
Se utiliza la función names() para enunciar los nombres de las columnas del marco de datos
names(mtcars)#
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
col.sin.d <- select(mtcars,-starts_with("d")) #Elimina las columnas cuyos nombres comiencen con una "d":
names(col.sin.d)
## [1] "mpg" "cyl" "hp" "wt" "qsec" "vs" "am" "gear" "carb"
col.names <- select(mtcars, -ends_with("t"))#Elimina las columnas cuyos nombres terminen en "t"
names(col.names)
## [1] "mpg" "cyl" "disp" "hp" "qsec" "vs" "am" "gear" "carb"
fruit <- c("apple","pear","orange","grape", "orange","orange")
x <- c(1,2,4,9,4,6)
y <- c(22,3,4,55,15,9)
z <- c(3,1,4,10,12,8)
(fruta2 <- data.frame(fruit,x,y,z))
## fruit x y z
## 1 apple 1 22 3
## 2 pear 2 3 1
## 3 orange 4 4 4
## 4 grape 9 55 10
## 5 orange 4 15 12
## 6 orange 6 9 8
NOTA:Esta acción mueve la columna z a la izquierda de todo lo demás y se convierte en la primera columna. A menudo es más conveniente tener columnas de uso frecuente a la izquierda. La palabra clave “everything” significa que todas las columnas restantes deben conservarse.
Se utiliza select_all() para aplicar una función a todas las columnas.
state <- c("Maryland", "Alaska", "New Jersey")
income <- c(76067,74444,73702)
median.us <- c(61372,61372,61372)
life.expectancy <- c(78.8,78.3,80.3)
(top.3.states <- data.frame(state, income, median.us,
life.expectancy)) #Antes de aplicar la función select_all() los nombres de las columnas no están en mayúscula
## state income median.us life.expectancy
## 1 Maryland 76067 61372 78.8
## 2 Alaska 74444 61372 78.3
## 3 New Jersey 73702 61372 80.3
Tambien se puede usar la función toupper() para colocar en mayúsculas los nombres de las columnas
(new.top.3.states <- select_all(top.3.states, toupper))
## STATE INCOME MEDIAN.US LIFE.EXPECTANCY
## 1 Maryland 76067 61372 78.8
## 2 Alaska 74444 61372 78.3
## 3 New Jersey 73702 61372 80.3
La función pull() aisla una columna especifica y actua similar a la sintaxis de R $
(top.3.states <- data.frame(state, income, median.us, life.expectancy))
## state income median.us life.expectancy
## 1 Maryland 76067 61372 78.8
## 2 Alaska 74444 61372 78.3
## 3 New Jersey 73702 61372 80.3
(pull.first.column <- pull(top.3.states,1)) #Para extraer la primera columna de datos
## [1] "Maryland" "Alaska" "New Jersey"
(pull.last.column <- pull(top.3.states,-1)) #Se usa un número negativo para extraer una columna de la derecha, es decir, -1 = columna más a la derecha
## [1] 78.8 78.3 80.3
nrow(mtcars) #se usa para saber el numero de filas originales del dataframe
## [1] 32
El siguiente código filtra cualquier elemento del conjunto de datos superior a 200, en cualquier columna.
(mtcars200 <- filter_all(mtcars, any_vars(. > 200)))
## mpg cyl disp hp drat wt qsec vs am gear carb
## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
## Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
## Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
names(mtcars)
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
cars_sin_p<-mtcars %>%
dplyr::select(-contains("p")) #Se Seleccionaron columnas que no tuvieran "p" en su nombre
names(cars_sin_p) #No se incluye ningún nombre de columna que tenga "p" en el nuevo marco de datos.
## [1] "cyl" "drat" "wt" "qsec" "vs" "am" "gear" "carb"
names(mtcars)
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
subset.mtcars <- select(mtcars,
matches("pg|gea")) #Los nombres de columna seleccionados contienen los caracteres "pg" o "gea"
names(subset.mtcars)
## [1] "mpg" "gear"
NOTA: La función “matches()” es más general que “contains” porque es una expresión regular y más flexible.
Las conexiones entre tablas se hacen usando “llaves” definidas. Si tengo una tabla A con US state abbrevation y población por estado; y la tabla B contiene Us state abbreviation y el nombre completo del estado. Si se quiere crear un nuevo dataframe que tenga el nombre completo del estado y la poblacion del estado se debe tomar, la abreviación del estado de la tabla A como la llave primaria y la breviación del estado en la tabla B como una llave foranea.
La función left_join() busca datos que coinciden entre ambos archivos usando una “llave” (by=“key”)
(us.state.areas <- as.data.frame(cbind(state.abb, state.area)))
## state.abb state.area
## 1 AL 51609
## 2 AK 589757
## 3 AZ 113909
## 4 AR 53104
## 5 CA 158693
## 6 CO 104247
## 7 CT 5009
## 8 DE 2057
## 9 FL 58560
## 10 GA 58876
## 11 HI 6450
## 12 ID 83557
## 13 IL 56400
## 14 IN 36291
## 15 IA 56290
## 16 KS 82264
## 17 KY 40395
## 18 LA 48523
## 19 ME 33215
## 20 MD 10577
## 21 MA 8257
## 22 MI 58216
## 23 MN 84068
## 24 MS 47716
## 25 MO 69686
## 26 MT 147138
## 27 NE 77227
## 28 NV 110540
## 29 NH 9304
## 30 NJ 7836
## 31 NM 121666
## 32 NY 49576
## 33 NC 52586
## 34 ND 70665
## 35 OH 41222
## 36 OK 69919
## 37 OR 96981
## 38 PA 45333
## 39 RI 1214
## 40 SC 31055
## 41 SD 77047
## 42 TN 42244
## 43 TX 267339
## 44 UT 84916
## 45 VT 9609
## 46 VA 40815
## 47 WA 68192
## 48 WV 24181
## 49 WI 56154
## 50 WY 97914
abbreviation.name <- as.data.frame(cbind(state.abb, state.name))
abbreviation.name[1:3,]
## state.abb state.name
## 1 AL Alabama
## 2 AK Alaska
## 3 AZ Arizona
info.area.name <- us.state.areas %>%
left_join(abbreviation.name, by = "state.abb") #Se uso la función left_join() para unir los 2 marco de datos
head(info.area.name)
## state.abb state.area state.name
## 1 AL 51609 Alabama
## 2 AK 589757 Alaska
## 3 AZ 113909 Arizona
## 4 AR 53104 Arkansas
## 5 CA 158693 California
## 6 CO 104247 Colorado
La función inner_join() genera solo las filas en ambos marcos de datos cuando la llave o clave son la misma. Todas las demás filas se eliminan.
#Primer data frame
names <- c("Sally","Tom","Frieda","Alfonzo")
team.scores <- c(3,5,2,7)
team.league <- c("alpha","beta","gamma", "omicron")
team.info <- data.frame(names, team.scores, team.league)
#Segundo data frame
names = c("Sally","Tom", "Bill", "Alfonzo")
school.grades <- c("A","B","C","B")
school.info <- data.frame(names, school.grades)
(school.and.team <- inner_join(team.info, school.info, by = "names")) #Los datos aparecen en el marco de datos de la escuela y el equipo solo cuando los nombres coinciden exactamente.
## names team.scores team.league school.grades
## 1 Sally 3 alpha A
## 2 Tom 5 beta B
## 3 Alfonzo 7 omicron B
La función anti_join() filtra filas del X basado en la presencia o ausencia de conincidencias en el Y.
#Primer data frame
names <- c("Sally","Tom","Frieda","Alfonzo")
team.scores <- c(3,5,2,7)
team.league <- c("alpha","beta","gamma", "omicron")
team.info <- data.frame(names, team.scores, team.league)
#Segundo data frame
names <- c("Sally","Tom", "Bill", "Alfonzo")
school.grades <- c("A","B","C","B")
(school.info <- data.frame(names, school.grades))
## names school.grades
## 1 Sally A
## 2 Tom B
## 3 Bill C
## 4 Alfonzo B
(nogrades <- anti_join(team.info, school.info, by = "names")) #Los datos provienen de team.info, pero solo se muestran los nombres que NO coinciden con los datos de calificaciones.
## names team.scores team.league
## 1 Frieda 2 gamma
La función full_join() conserva todos los valores de ambos marcos de datos.
#Primer data frame
names = c("Sally","Tom","Frieda","Alfonzo")
team.scores = c(3,5,2,7)
team.league = c("alpha","beta","gamma", "omicron")
team.info = data.frame(names, team.scores, team.league)
#Segundo data frame
names = c("Sally","Tom", "Bill", "Alfonzo")
school.grades = c("A","B","C","B")
school.info = data.frame(names, school.grades)
(team.info.and.or.grades <- full_join(team.info, school.info, by = "names"))#Se creo un nuevo data frame utilizando la full join ()
## names team.scores team.league school.grades
## 1 Sally 3 alpha A
## 2 Tom 5 beta B
## 3 Frieda 2 gamma <NA>
## 4 Alfonzo 7 omicron B
## 5 Bill NA <NA> C
La función semi_join() conserva todos las observaciones del grupo de datos 1 que coinciden con el grupo de datos 2. El orden en que se pongan los marcos de datos determinara el resultado.
(team.info.with.grades <- semi_join(team.info, school.info)) # DPLYR comprende que "names" es una clave común.
## Joining, by = "names"
## names team.scores team.league
## 1 Sally 3 alpha
## 2 Tom 5 beta
## 3 Alfonzo 7 omicron
La función rigth_join(x, y, by=common_key), esta retorna todas las filas de y y las columnas de ambos (x y y). En donde no haya conincidencia el valor será NA, si hay varias coincidencias entre X y Y se incluiran todas.
us.state.areas <- as.data.frame(cbind(state.abb, state.area))
us.state.areas[1:3,]
## state.abb state.area
## 1 AL 51609
## 2 AK 589757
## 3 AZ 113909
us.state.abbreviation.and.name <- as.data.frame(cbind(state.abb,
state.name))
us.state.abbreviation.and.name[1:3,]
## state.abb state.name
## 1 AL Alabama
## 2 AK Alaska
## 3 AZ Arizona
us.state.abbreviation.and.name[1,1] <- "Intentional Mismatch"
us.state.with.abbreviation.and.name.and.area <- right_join(us.state.areas,
us.state.abbreviation.and.name, by = "state.abb")
us.state.with.abbreviation.and.name.and.area[1:3,] #Alabama se reemplaza con "intentional mismatch". Como resultado, falta en la salida. Sin embargo, se incluyen todas las columnas de ambos conjuntos de datos
## state.abb state.area state.name
## 1 AK 589757 Alaska
## 2 AZ 113909 Arizona
## 3 AR 53104 Arkansas
La función slice() proporciona una forma de incluir filas o rangos de filas específicas en sus conjuntos de datos.
msleep <- ggplot2::msleep
nrow(msleep) #inicialmente 83 filas
## [1] 83
msleep.only.first.5 <- slice(msleep, -6:-n())#Las filas 6 a 83 se eliminan.
# La expresión “n (“) ”es el número total de filas por lo que, no es necesarios saber el numero de filas del marco de datos.
nrow(msleep.only.first.5) #Ahora solo se conservan las cinco primeras filas
## [1] 5
msleep.20.rows <- msleep %>%
slice(20:39)
nrow(msleep.20.rows)#Ahora solo se conservan 20 filas
## [1] 20
nrow(msleep) - nrow(msleep.20.rows) #muestra la diferencia entre el marco de datos original y cortado (o tibble)
## [1] 63
summarise() combinado con group_by (), proporciona un gran variedad de herramientas prácticas y rápidas para dimensionar datos (contar, sumar, desviación estándar y otras funciones) con una o más variables categóricas.
library(MASS)
##
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
##
## select
data(gehan)
gehan2 <- gehan
library(tidyverse)
gehan2 %>% summarise( kount = n()) #Número de pacientes que participaron en el ensayo medico
## kount
## 1 42
gehan2 %>%
group_by(treat) %>%
summarise(kount = n()) #Recuento por tratamiento/sin tratamiento
## # A tibble: 2 × 2
## treat kount
## <fct> <int>
## 1 6-MP 21
## 2 control 21
gehan2 %>%
group_by(treat) %>%
summarise(average.remiss.time = mean(time),
median.remiss.time = median(time),
std.dev.remiss.time = sd(time),
median.abs.deviation = mad(time),
IQR.remiss.time = IQR(time)) # Muestra las estadística generales de tratamiento / sin tratamiento
## # A tibble: 2 × 6
## treat average.remiss.time median.remiss.t… std.dev.remiss.… median.abs.devi…
## <fct> <dbl> <int> <dbl> <dbl>
## 1 6-MP 17.1 16 10.0 10.4
## 2 control 8.67 8 6.47 5.93
## # … with 1 more variable: IQR.remiss.time <dbl>
gehan2 %>%
group_by(treat) %>%
summarise(minimum.remission = min(time),
max.remission = max(time)) #summarise() se puede utilizar para encontrar el mínimo / máximo dentro del group_by()
## # A tibble: 2 × 3
## treat minimum.remission max.remission
## <fct> <int> <int>
## 1 6-MP 6 35
## 2 control 1 23
subset.survey <- survey[1:10,]
library(dplyr)
head(subset.survey)
## Sex Wr.Hnd NW.Hnd W.Hnd Fold Pulse Clap Exer Smoke Height M.I
## 1 Female 18.5 18.0 Right R on L 92 Left Some Never 173.00 Metric
## 2 Male 19.5 20.5 Left R on L 104 Left None Regul 177.80 Imperial
## 3 Male 18.0 13.3 Right L on R 87 Neither None Occas NA <NA>
## 4 Male 18.8 18.9 Right R on L NA Neither None Never 160.00 Metric
## 5 Male 20.0 20.0 Right Neither 35 Right Some Never 165.00 Metric
## 6 Female 18.0 17.7 Right L on R 64 Right Some Never 172.72 Imperial
## Age
## 1 18.250
## 2 17.583
## 3 16.917
## 4 20.333
## 5 23.667
## 6 21.000
subset.survey %>%
na.omit() %>% #remove any NAs
group_by(Sex) %>%
summarise(across(where(is.numeric), mean,
.names = "mean_{col}")) %>%
head()# head () sin marco de datos especificado, usa el marco de datos o tibble que se esta trabajando en el chunk
## # A tibble: 2 × 6
## Sex mean_Wr.Hnd mean_NW.Hnd mean_Pulse mean_Height mean_Age
## <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Female 17.8 17.7 76.7 168. 25.0
## 2 Male 19.1 19.2 76.8 174. 20.3
new.sleep <- msleep %>% #Base de datos msleep
group_by(vore, order)
(s<-summarise(new.sleep, n())) #uso summarise() para contar las combinaciones vore-order
## `summarise()` has grouped output by 'vore'. You can override using the `.groups` argument.
## # A tibble: 32 × 3
## # Groups: vore [5]
## vore order `n()`
## <chr> <chr> <int>
## 1 carni Carnivora 12
## 2 carni Cetacea 3
## 3 carni Cingulata 1
## 4 carni Didelphimorphia 1
## 5 carni Primates 1
## 6 carni Rodentia 1
## 7 herbi Artiodactyla 5
## 8 herbi Diprotodontia 1
## 9 herbi Hyracoidea 2
## 10 herbi Lagomorpha 1
## # … with 22 more rows
(new.sleep.totals <- msleep %>%
group_by(vore, order) %>%
summarise(n())) #Para obtener solo los totales de las
## `summarise()` has grouped output by 'vore'. You can override using the `.groups` argument.
## # A tibble: 32 × 3
## # Groups: vore [5]
## vore order `n()`
## <chr> <chr> <int>
## 1 carni Carnivora 12
## 2 carni Cetacea 3
## 3 carni Cingulata 1
## 4 carni Didelphimorphia 1
## 5 carni Primates 1
## 6 carni Rodentia 1
## 7 herbi Artiodactyla 5
## 8 herbi Diprotodontia 1
## 9 herbi Hyracoidea 2
## 10 herbi Lagomorpha 1
## # … with 22 more rows
La función gather() convierte varias columnas en una sola columna. Las tasas de natalidad entre adolescentes, por cada 1000 mujeres, son de www.cdc.gov
state <- c("Maryland", "Alaska", "New Jersey")
income <- c(76067,74444,73702)
median.us <- c(61372,61372,61372)
life.expectancy <- c(78.8,78.3,80.3)
teen.birth.rate.2015 <- c(17,29.3,12.1)
teen.birth.rate.2007 <- c(34.3,42.9,24.9)
teen.birth.rate.1991 <- c(54.1, 66, 41.3)
top.3.states <- data.frame(state, income, median.us,
life.expectancy,
teen.birth.rate.2015, teen.birth.rate.2007,
teen.birth.rate.1991)
names(top.3.states) <- c("state", "income", "median.us",
"life.expectancy","2015","2007","1991")
top.3.states
## state income median.us life.expectancy 2015 2007 1991
## 1 Maryland 76067 61372 78.8 17.0 34.3 54.1
## 2 Alaska 74444 61372 78.3 29.3 42.9 66.0
## 3 New Jersey 73702 61372 80.3 12.1 24.9 41.3
(new.top.3.states <- top.3.states %>%
gather("2015", "2007", "1991", key = "year", value = "cases")) #Se usa gather() para recopilar los tres años en una sola columna
## state income median.us life.expectancy year cases
## 1 Maryland 76067 61372 78.8 2015 17.0
## 2 Alaska 74444 61372 78.3 2015 29.3
## 3 New Jersey 73702 61372 80.3 2015 12.1
## 4 Maryland 76067 61372 78.8 2007 34.3
## 5 Alaska 74444 61372 78.3 2007 42.9
## 6 New Jersey 73702 61372 80.3 2007 24.9
## 7 Maryland 76067 61372 78.8 1991 54.1
## 8 Alaska 74444 61372 78.3 1991 66.0
## 9 New Jersey 73702 61372 80.3 1991 41.3
La función spread()condensa los datos de una misma observación que se encuentran en varias filas, en una sola.
(dat1 <- data.frame(Type = c("TypeA", "TypeA", "TypeB", "TypeB"), Answer = c("Yes", "No", NA, "No"), n = 1:4))
## Type Answer n
## 1 TypeA Yes 1
## 2 TypeA No 2
## 3 TypeB <NA> 3
## 4 TypeB No 4
(dat2 <- dat1 %>%
filter(!is.na(Answer)) %>%
spread(key=Answer, value=n)) #Después de usar spread, las respuestas "No" y "Sí" están en columnas separadas, lo que facilita los resúmenes y otros análisis
## Type No Yes
## 1 TypeA 2 1
## 2 TypeB 4 NA
La función separate() puede dividir una columna en dos o más.
#La columna teen.birth tiene tres datos por fila, separados por un carácter especial ("//").
state <- c("Maryland", "Alaska", "New Jersey")
income <- c(76067,74444,73702)
median.us <- c(61372,61372,61372)
life.expectancy <- c(78.8,78.3,80.3)
teen.birth <- c("17//34.3//54.1", "29.0//42.9//66.0", "12.1//24.9//41.3")
(top3<- data.frame(state, income, median.us,
life.expectancy,teen.birth))
## state income median.us life.expectancy teen.birth
## 1 Maryland 76067 61372 78.8 17//34.3//54.1
## 2 Alaska 74444 61372 78.3 29.0//42.9//66.0
## 3 New Jersey 73702 61372 80.3 12.1//24.9//41.3
(top3.separated<- top3 %>%
separate(teen.birth, into = c("2015", "2007","1991"), sep = "//")) # Antes de ejecutar la función separate, los años 2015, 2007 y 1991 se combinan en la columna de nacimiento de adolescentes.
## state income median.us life.expectancy 2015 2007 1991
## 1 Maryland 76067 61372 78.8 17 34.3 54.1
## 2 Alaska 74444 61372 78.3 29.0 42.9 66.0
## 3 New Jersey 73702 61372 80.3 12.1 24.9 41.3
DPLYR contiene una gran cantidad de funciones útiles para transformar los datos en lo que se necesite para resolver problemas analíticos. Los datos reales a menudo tienen valores perdidos, valores numéricamente válidos pero incorrectos, estructuras extrañas y muchas otras variaciones. El siguiente conjunto de herramientas se pueden utilizar junto con las cinco funciones clave de DPLYR o, en algunos casos, de forma independiente. El manual DPLYR tiene mas información de interes.
La función n() se encarga de hacer recuentos de datos. Esta función se aplica para funciones como mutate(), summarise() y filter().
m <- mutate(new.sleep, kount = n()) # Nueva variable, kount agregado en el extremo derecho
m[1:5,c(1:4,10:12)] #Se limita el numero de columnas para que se puedan ver en la página
## # A tibble: 5 × 7
## # Groups: vore, order [5]
## name genus vore order brainwt bodywt kount
## <chr> <chr> <chr> <chr> <dbl> <dbl> <int>
## 1 Cheetah Acinonyx carni Carnivora NA 50 12
## 2 Owl monkey Aotus omni Primates 0.0155 0.48 10
## 3 Mountain beaver Aplodontia herbi Rodentia NA 1.35 16
## 4 Greater short-tailed shrew Blarina omni Soricomorp… 0.00029 0.019 3
## 5 Cow Bos herbi Artiodacty… 0.423 600 5
f <- filter(new.sleep, n() > 14)#Filtrar por recuento de pedidos superiores a 14
f[1:5,c(1:4,10:11)]
## # A tibble: 5 × 6
## # Groups: vore, order [1]
## name genus vore order brainwt bodywt
## <chr> <chr> <chr> <chr> <dbl> <dbl>
## 1 Mountain beaver Aplodontia herbi Rodentia NA 1.35
## 2 Guinea pig Cavis herbi Rodentia 0.0055 0.728
## 3 Chinchilla Chinchilla herbi Rodentia 0.0064 0.42
## 4 Western american chipmunk Eutamias herbi Rodentia NA 0.071
## 5 Mongolian gerbil Meriones herbi Rodentia NA 0.053
#Ingresar primero estos datos
salary.description <- c("Golden parachute type","Well to do",
"Average","Below average", "bring date seeds instead of flowers")
first(salary.description)
## [1] "Golden parachute type"
#Despúes ingresar
last(salary.description)
## [1] "bring date seeds instead of flowers"
#Tercera observación desde el final
nth(salary.description, -3)
## [1] "Average"
#Segundo elemento del vector
nth(salary.description,2)
## [1] "Well to do"
La función n_distinct() determina cuantos valores unicos hay en un vector.
a.vector <- c(22,33,44,1,2,3,3,3,4)
(original.length <- length(a.vector)) #Tiene encuenta todos los datos del vector, incluso los que se repiten
## [1] 9
(distinct.a.vector <- n_distinct(a.vector)) #Muestra el total de valores del vector sin tener en cuenta las repeticiones que haya de algun dato
## [1] 7
(test1 <- if_else(original.length == distinct.a.vector, "all values unique","some duplicate values in vector")) #Si se repite algun valor mostrara un mensaje que lo indique
## [1] "some duplicate values in vector"
b.vector <- c(1,2,3,4,5,6)
length(b.vector)
## [1] 6
(distinct.b.vector <- n_distinct(b.vector))#Muestra el recuento (total) de números distintos
## [1] 6
(test2 <- if_else(length(b.vector) == distinct.b.vector, "all values unique", "duplicates")) #Si hay valores unicos mostrara un mensaje que lo indique
## [1] "all values unique"
La función na_if() puede establecer un valor de cálculo en un procedimiento indeterminado, especificando “NA”
test <- c(100, 0, 999)
(x <- 5000/test) #Dividir entre 0 es una operación indetermina que tiende al infinito
## [1] 50.000000 Inf 5.005005
#En lugar de tener un valor de infinito en el vector resultante, puede programarse en R para que sustituya el "Inf" por "NA"
(x1 <- 5000/na_if(test,0))
## [1] 50.000000 NA 5.005005
class(x)
## [1] "numeric"
La función coalesce() reemplaza los valores perdidos de un vector con cero o algún otro valor.
(y <- c(33,4,11,NA,9)) #antes de reemplazar los NA
## [1] 33 4 11 NA 9
(y<- coalesce(y,0)) #reemplazando los valores con la función coalesce
## [1] 33 4 11 0 9
w <- c(100,4,12,6,8,3)
(rank1 <-row_number(y))
## [1] 5 2 4 1 3
w[rank1[1]] #me muestra el número más pequeño
## [1] 8
w[rank1[6]] #me muestra el número más grande
## [1] NA
(rank2 <- min_rank(w))
## [1] 6 2 5 3 4 1
(rank3 <- dense_rank(w))
## [1] 6 2 5 3 4 1
(rank4 <- percent_rank(w)) #El primer elemento de "y" está en el percentil 100
## [1] 1.0 0.2 0.8 0.4 0.6 0.0
#el segundo elemento de "y" está en el percentil
#el último elemento de "y" está en el percentil 0:
La función cume_dist() muestra la proporción de todos los valores menores o iguales al rango actual
(rank5 <- cume_dist(w))
## [1] 1.0000000 0.3333333 0.8333333 0.5000000 0.6666667 0.1666667
(rank6 = ntile(w, 3)) #Se divide el vector de entrada en 3 depositos
## [1] 3 1 3 2 2 1
test.vector <- c(2,22,33,44,77,89,99)
quantile(test.vector, prob = seq(0,1,length = 11),type = 5) #La función quantile() de R tiene una salida fácil de leer
## 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
## 2.0 6.0 20.0 28.6 36.3 44.0 67.1 81.8 90.0 97.0 99.0
Cuando los grupos de datos son muy grandes es dificíl manejarlos y se requiere de un muestreo o resumen intermedio de los datos.
data("ChickWeight")
(my.sample <- sample_n(ChickWeight, 5)) #se escoge al azar 5 filas del grupo de datos ChickWeight
## weight Time Chick Diet
## 1 48 4 5 1
## 2 151 18 30 2
## 3 164 14 5 1
## 4 175 21 23 2
## 5 41 0 6 1
NOTA: Se debe establecer un número de semilla cada vez que desee una muestra para que otros puedan reproducir el procedimiento. De lo contrario, cada vez que se ejecuta la rutina, se pueden obtener resultados diferentes.
set.seed(833)
Muestrear con replace = TRUE significa que puede obtener la misma fila o elemento más de una vez. Su elección de True o False para el reemplazo depende de su propósito. Si, por ejemplo, está investigando defectos de fabricación, es posible que desee utilizar replace = FALSE, ya que no quiere perder el tiempo investigando el mismo defecto de nuevo.
(mysample <- sample_n(ChickWeight, 10, replace = TRUE))
## weight Time Chick Diet
## 1 98 8 45 4
## 2 42 0 17 1
## 3 98 8 36 3
## 4 51 2 11 1
## 5 198 20 3 1
## 6 237 21 49 4
## 7 205 16 50 4
## 8 170 16 39 3
## 9 332 18 35 3
## 10 144 14 33 3
mysample1 <- sample_n(mtcars, 12, weight = cyl)
mysample1[,1:5] #En este ejemplo es más probable que los automóviles con más cilindros se seleccionen como parte de la muestra
## mpg cyl disp hp drat
## AMC Javelin 15.2 8 304.0 150 3.15
## Porsche 914-2 26.0 4 120.3 91 4.43
## Merc 280 19.2 6 167.6 123 3.92
## Cadillac Fleetwood 10.4 8 472.0 205 2.93
## Merc 240D 24.4 4 146.7 62 3.69
## Datsun 710 22.8 4 108.0 93 3.85
## Merc 280C 17.8 6 167.6 123 3.92
## Mazda RX4 Wag 21.0 6 160.0 110 3.90
## Merc 450SLC 15.2 8 275.8 180 3.07
## Chrysler Imperial 14.7 8 440.0 230 3.23
## Maserati Bora 15.0 8 301.0 335 3.54
## Valiant 18.1 6 225.0 105 2.76
Se utiliza la función sample_frac() para obtener una muestra igual a un porcentaje específico de las filas del marco de datos
(t12 <- sample_frac(ChickWeight, 0.02))
## weight Time Chick Diet
## 1 48 2 13 1
## 2 62 6 12 1
## 3 197 20 45 4
## 4 234 18 42 4
## 5 58 4 28 2
## 6 163 16 3 1
## 7 103 8 41 4
## 8 103 8 42 4
## 9 120 18 19 1
## 10 48 2 36 3
## 11 80 6 48 4
## 12 137 12 33 3
by_hair_color <- starwars %>% group_by(hair_color) #group_by () identifica a los personajes de Starwars por grupo de cabello, y luego se selecciona el 7% de los registros en cada grupo. Esto es útil cuando desea un porcentaje establecido de grupos cuyos tamaños varían
otrosam <- sample_frac(by_hair_color, .07, replace = TRUE)
otrosam[,1:5]
## # A tibble: 5 × 5
## # Groups: hair_color [3]
## name height mass hair_color skin_color
## <chr> <int> <dbl> <chr> <chr>
## 1 Eeth Koth 171 NA black brown
## 2 Dormé 165 NA brown light
## 3 Sebulba 112 40 none grey, red
## 4 Shaak Ti 178 57 none red, blue, white
## 5 Tion Medon 206 80 none grey
(row.kount.only <- ChickWeight %>% tally()) #La función tally() proporciona recuentos del total de los datos
## n
## 1 578
(diet.kount <- ChickWeight %>% count(Diet)) #La función count() proporcionan recuentos por grupo de datos.
## Diet n
## 1 1 220
## 2 2 120
## 3 3 120
## 4 4 118
especies_unic <- starwars %>%
add_count(species) %>% #add_count() es util para el filtrado grupal de datos
filter(n == 1)
especies_unic[,1:6]
## # A tibble: 29 × 6
## name height mass hair_color skin_color eye_color
## <chr> <int> <dbl> <chr> <chr> <chr>
## 1 Greedo 173 74 <NA> green black
## 2 Jabba Desilijic Tiure 175 1358 <NA> green-tan, brown orange
## 3 Yoda 66 17 white green brown
## 4 Bossk 190 113 none green red
## 5 Ackbar 180 83 none brown mottle orange
## 6 Wicket Systri Warrick 88 20 brown brown brown
## 7 Nien Nunb 160 68 none grey black
## 8 Nute Gunray 191 90 none mottled green red
## 9 Watto 137 NA black blue, grey yellow
## 10 Sebulba 112 40 none grey, red orange
## # … with 19 more rows
data(mtcars)
names(mtcars)
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
mtcars <- rename(mtcars, spam_mpg = mpg)
names(mtcars)
## [1] "spam_mpg" "cyl" "disp" "hp" "drat" "wt"
## [7] "qsec" "vs" "am" "gear" "carb"
La función case_when() es particularmente útil dentro de la función mutate(). Esta puede crear una nueva variable que se base en una combinación compleja de variables existentes.
data(starwars)
(new.starwars <- starwars %>%
dplyr::select(name, mass, gender, species, height) %>%
mutate(type = case_when(height > 200 | mass > 200 ~ "large",
species == "Droid" ~ "robot", TRUE ~ "other")))
## # A tibble: 87 × 6
## name mass gender species height type
## <chr> <dbl> <chr> <chr> <int> <chr>
## 1 Luke Skywalker 77 masculine Human 172 other
## 2 C-3PO 75 masculine Droid 167 robot
## 3 R2-D2 32 masculine Droid 96 robot
## 4 Darth Vader 136 masculine Human 202 large
## 5 Leia Organa 49 feminine Human 150 other
## 6 Owen Lars 120 masculine Human 178 other
## 7 Beru Whitesun lars 75 feminine Human 165 other
## 8 R5-D4 32 masculine Droid 97 robot
## 9 Biggs Darklighter 84 masculine Human 183 other
## 10 Obi-Wan Kenobi 77 masculine Human 182 other
## # … with 77 more rows
Nota importante A veces, los paquetes R tienen funciones con el mismo nombre que provocan una confusión. Tanto MASS como DPLYR tienen la misma función, “select”. Para asegurarse de que se utiliza el paquete DPLYR, utilice dplyr :: select como función. Esa sintaxis obliga a R a usar DPLYR en lugar de la versión MASS de select