library(knitr)
\[ \color{blue}{Filtro~de~condición~única}\]
En el siguente codigo de la base de datos “mtcars” se selecciona los carros que solo tienen 6 cilindros (cyl) y el doble (==)significa que solo se selecciona los carros con 6 cilindros
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5 v purrr 0.3.4
## v tibble 3.1.5 v dplyr 1.0.7
## v tidyr 1.1.4 v stringr 1.4.0
## v readr 2.0.2 v forcats 0.5.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
data("mtcars")
#select only cars with six cylinders
six.cyl.only <- filter(mtcars, cyl == 6)
six.cyl.only
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
## Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
## Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
## Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
\[ \color{blue}{Filtro~de~condiciones~múltiples}\] En este codigó se seleciona los carros con 6 cilindros que tengan 110 caballos de fuerza, igualmente el doble signo igual (==) se usa para decir que quiero los datos solo con esas valores o caracteristicas
six.cylinders.and.110.horse.power <- filter(mtcars, cyl == 6,
hp == 110)
six.cylinders.and.110.horse.power
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
\[\color{blue}{OR~Lógica~para~el~filtrado}\] En este codigó se pide que se selecciones los carros con 4 engranajes, y se unsa la barra vertical (|) es decir filtrar datos de carros con 4 engranajes, además de seleccionar tambíen carros con más de 6 cilindros
gear.eq.4.or.more.than.8 <- filter(mtcars, gear == 4|cyl > 6)
gear.eq.4.or.more.than.8
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
## Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
## Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
## Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
## Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 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
## Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
## Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
## Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
## 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
## Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
## 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
## Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2
\[\color{blue}{Filtrar~por~mínimos,~máximos~y~otros~criterios~numéricos}\] En este codigó se presenta, una sola fila con el menor desplazamiento del motor.
smallest.engine.displacement <- filter(mtcars, disp ==
min(disp))
smallest.engine.displacement
## mpg cyl disp hp drat wt qsec vs am gear carb
## Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.9 1 1 4 1
Ahora se presenta el Filtrardo con condiciones separadas por comas, en la base de datos (chickWeight) donde se pide el tiempo menor a 3 y un peso mayor a 53
data("ChickWeight")
chick.subset <- filter(ChickWeight, Time < 3, weight > 53)
chick.subset
## weight Time Chick Diet
## 1 55 2 22 2
## 2 55 2 40 3
## 3 55 2 43 4
## 4 54 2 50 4
\[\color{blue}{Filtrar~valores~perdidos~(NA)~para~una~columna~específica}\] En la base de datos “airquality” en la quita fila y primera columna tiene un dato faltante, en este codigó se filtra los 10 datos antes de filtrar el dato faltante
data("airquality")
head(airquality,10) #before filter
## 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
En este codigó elimino cualquier fila con valores perdidos en la columna Ozono, por ejemplo las de la fila 5 y 10, pero el dato faltante de Solar.R sigue en la segunda columna
no.missing.ozone = filter(airquality, !is.na(Ozone))
head(no.missing.ozone,8) #after filter
## 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
\[\color{blue}{Filtrar~filas~con~NA~en~cualquier~lugar~del~conjunto~de~dato}\]
En caso que quiero eliminar todos los que no tengo datos puedo usar complete.cases () para eliminar cualquier fila que contenga un NA en cualquier columna
airqual.no.NA.anywhere<-filter(airquality[1:10,],complete.cases(airquality[1:10,]))
airqual.no.NA.anywhere
## 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
\[\color{blue}{Filtrar~por~(porcentaje)~en~(porcentaje)}\]
“%en%” es un operador poderoso, que proporciona una forma abreviada conveniente para incluir / excluir valores especificados, por ejemplo en la base de datos “iris”
data("iris")
table(iris$Species) #counts of species in the dataset
##
## setosa versicolor virginica
## 50 50 50
iris.two.species <- filter(iris,Species %in% c("setosa", "virginica"))
table(iris.two.species$Species)
##
## setosa versicolor virginica
## 50 0 50
nrow(iris); nrow(iris.two.species)
## [1] 150
## [1] 100
data("airquality")
airqual.3.columns <- filter(airquality, Ozone > 29)[,1:3]
head(airqual.3.columns)
## 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
\[\color{blue}{Filtrar~por~frecuencia~total~de~un~valor~en~todas~las~filas}\] Esta lógica utiliza “group_by” para permitir el recuento de filas en función del número de engranajes en la base de datos de “mtcars”
table(mtcars$gear)
##
## 3 4 5
## 15 12 5
more.frequent.no.of.gears <- mtcars %>%
group_by(gear) %>%
filter(n() > 10) #
table(more.frequent.no.of.gears$gear)
##
## 3 4
## 15 12
Se pueden agregar criterios adicionales al filtro si se incluye el requisito de que la potencia sea inferior a 105
more.frequent.no.of.gears.and.low.horsepower <- mtcars %>%
group_by(gear) %>%
filter(n() > 10, hp < 105)
table(more.frequent.no.of.gears.and.low.horsepower$gear)
##
## 3 4
## 1 7
\[\color{red}{Nota~=~En~Markdowm~me~sale~que~la~función~porcentaje>porcentaje~no~se~encuentra...}\]
\[\color{red}{~al~pasar~knit~no~me~sale~lo~que~necesito}\]
\[\color{blue}{Filtrar~por~nombre~de~columna~usando~"comienza~con"}\] En el siguente codigo de datos de “iris” …
names(iris) #show the column names
## [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
iris.display <- iris %>% dplyr::select(starts_with("S"))
head(iris.display) #use la cabeza para reducir el número de filas de salida
## 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
\[\color{blue}{Filtrar~filas:~las~columnas~cumplen~los~criterios~(filter~at)}\] Se puede utilizar filter_at para buscar filas que cumplan con algunos criterios, como máximo:
new.mtcars <- mtcars %>% filter_at(vars(cyl, hp),all_vars(. == max(.)))
new.mtcars
## 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
Tenga en cuenta que solo un automóvil, el Maserati Bora, tenía tanto el número máximo de cilindros como la potencia máxima para cada columna, respectivamente.
Otro ejemplo de conjunto de datos proviene del blog de Suzan Baert (https://suzan.rbind.io/2018/02/dplyr-tutorial-3/#filter-at), utilizando la investigación del estudio del sueño.
Cargue el marco de datos msleep del paquete ggplot2:
msleep <- ggplot2::msleep
msleep.over.5 <- msleep %>% select(name, sleep_total:sleep_rem, brainwt:bodywt) %>% filter_at(vars(contains("sleep")), all_vars(.>5))
msleep.over.5
## # A tibble: 2 x 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
Para el código anterior, ignore la declaración de selección por el momento (se explica más adelante). La función filter_at dice que mire solo las variables que contienen la palabra “dormir”. Dentro de esas variables (en este caso, dos de ellas), filtre por cualquier valor mayor que 5. El “.” significa cualquier variable con dormir en el nombre. En este caso, solo dos filas cumplieron los criterios para el filtro.
\[\color{blue}{Organizar~(ordenar)}\] Organizar, la función de clasificación, es tan antigua como el alfabeto. Según el orden ASCII definido, reorganiza un marco de datos o un vector en una secuencia definida como ascendente o descendente. Las claves de clasificación se definen como primarias, secundarias, etc. Cargue el marco de datos msleep del paquete ggplot2
msleep <- ggplot2::msleep
msleep[,1:4]
## # A tibble: 83 x 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
\[\color{blue}{Ascendente}\]
animal.name.sequence <- arrange(msleep, vore, order)
animal.name.sequence[,1:4]
## # A tibble: 83 x 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
\[\color{blue}{Descendiendo}\]
animal.name.sequence.desc <- arrange(msleep, vore, desc(order))
head(animal.name.sequence.desc[,1:4])
## # A tibble: 6 x 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
En la sección “Mutar”, verá cómo se puede crear una variable sobre la marcha y luego usarla en la misma declaración para ordenar.
\[\color{blue}{Renombrar}\] Renombrar permite cambiar el nombre de una o más columnas. Es una función de conveniencia y no cambia datos.
Se puede cambie el nombre de una o más columnas en un conjunto de datos:
names(iris)
## [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
Mostrar nuevos nombres de columna:
renamed.iris <- rename(iris, width.of.petals = Petal.Width,various.plants.and.animals = Species)
names(renamed.iris)
## [1] "Sepal.Length" "Sepal.Width"
## [3] "Petal.Length" "width.of.petals"
## [5] "various.plants.and.animals"
\[\color{blue}{Mutate}\] Con la función mutate() podemos computar tranformaciones de variables en un data frame. A menudo, tendremos la necesidad de crear nuevas variables que se calculan a partir de variables existentes,mutate() nos proporciona una interface clara para realizar este tipo de operaciones.
Mutate agrega nuevas variables a un marco de datos. Requiere el marco de datos original como primer argumento y luego los argumentos para crear nuevas variables como los argumentos restantes. El siguiente ejemplo agrega el registro natural de longitud y peso al marco de datos creado anteriormente que contiene solo las variables de longitud y peso
Agregue una nueva variable calculada a un marco de datos:
data("ChickWeight")
ChickWeight[1:2,] #first two rows
## weight Time Chick Diet
## 1 42 0 1 1
## 2 51 2 1 1
Primeras dos filas, con un nuevo campo agregado:
Chickweight.with.log <- mutate(ChickWeight,log.of.weight = log10(weight))
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
\[\color{blue}{mutate~all~para~agregar~nuevos~campos~de~una~vez}\] Cree una serie de nuevos campos basados en algún cálculo utilizando campos existentes. Este es un enfoque abreviado, por lo que no es necesario definir específicamente cada nueva variable. En el siguiente ejemplo, cada una de las columnas designadas (6–11) proporciona números a la función de raíz cuadrada y luego crea una nueva columna con el sufijo “_ raíz cuadrada”.
Cargue el marco de datos msleep del paquete ggplot2:
msleep <- ggplot2::msleep
names(msleep)
## [1] "name" "genus" "vore" "order" "conservation"
## [6] "sleep_total" "sleep_rem" "sleep_cycle" "awake" "brainwt"
## [11] "bodywt"
Ahora agregue las variables / columnas de raíz cuadrada para las variables numéricas en las columnas 6-11:
msleep.with.square.roots <- mutate_all(msleep[,6:11], funs("square root" = sqrt( . )))
## 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(msleep.with.square.roots)
## [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"
msleep.with.square.roots
## # A tibble: 83 x 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>
\[\color{blue}{mutate~at~para~agregar~campos}\] Las variables para rango de clase, rango de edad y rango de sobrevivientes se crean de la siguiente manera, utilizando el conjunto de datos de sobrevivientes del Titanic. Usando la función de datos, Titanic se carga como una tabla; as.data.frame se usa para convertir a un dataframe:
data("Titanic")
Titanic <- as.data.frame(Titanic)
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
titanic.with.ranks <- mutate_at(Titanic, vars(Class,Age,Survived),funs(Rank = min_rank(desc(.))))
head(titanic.with.ranks)
## 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
\[\color{blue}{mutate~if}\] mutate_if combina la lógica IF y mutate para crear una nueva variable o alterar una existente. 1 Los siguientes son dos ejemplos. En el ejemplo uno, los factores se eliminan para su conveniencia posterior. El ejemplo dos muestra cómo los NA en una columna se pueden reemplazar por cero.
Ejemplo # 1 Cree una función simple para dividir un número entre 10:
Utilice el conjunto de datos CO2 incorporado para ilustrar:
divide.by.10 <- function (a.number) (a.number / 10)
head(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
Ahora divida cualquier columna que tenga un formato numérico por 10, utilizando la función personalizada anterior
new.df <- CO2 %>%
mutate_if(is.numeric, divide.by.10)
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
Cualquier NA en un campo numérico se reemplaza por cero. “Coalesce” es una función de DPLYR que encuentra el primer valor que no falta en cada posición. Un conjunto de tres puntos en R (y otros idiomas) se llama puntos suspensivos. Significa que una función aceptará cualquier número de argumentos.
df <- data.frame(alpha = c(22, 1, NA),almond = c(0, 5, 10),grape = c(0, 2, 2),apple = c(NA, 5, 10))
df
## alpha almond grape apple
## 1 22 0 0 NA
## 2 1 5 2 5
## 3 NA 10 2 10
df.fix.alpha <- df %>% mutate_if(is.numeric, coalesce, ... = 0)
df.fix.alpha
## alpha almond grape apple
## 1 22 0 0 0
## 2 1 5 2 5
## 3 0 10 2 10
\[\color{blue}{Detección~de~cadena~e~indicador~de~duplicado~verdadero~/~falso}\] Todas las columnas con los caracteres “dormir” en el nombre de la columna se convierten en carácter. Cargue el marco de datos msleep del paquete ggplot2:
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
Agregue un campo que indique si un valor particular en una columna ocurre más de una vez.
En este caso, la columna es conservación:
msleep.with.dup.indicator <- mutate(msleep, duplicate.indicator = duplicated(conservation))
msleep.with.dup.indicator[1:6,]
## # A tibble: 6 x 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>
Tenga en cuenta el nuevo campo, duplicate.indicator, que se muestra en la parte inferior. Mutate agrega un campo que indica si un valor particular en una columna ocurre más de una vez. En este caso, la columna es conservación. La Figura 1-1 muestra una vista parcial de msleep.with.dup.indicator, con el campo del indicador duplicado claramente mostrado.
msleep.with.dup.indicator <- mutate(msleep,duplicate.indicator = duplicated(conservation))
msleep.with.dup.indicator[1:6,c(1,2,3,12)]
## # A tibble: 6 x 4
## name genus vore duplicate.indicator
## <chr> <chr> <chr> <lgl>
## 1 Cheetah Acinonyx carni FALSE
## 2 Owl monkey Aotus omni FALSE
## 3 Mountain beaver Aplodontia herbi FALSE
## 4 Greater short-tailed shrew Blarina omni TRUE
## 5 Cow Bos herbi FALSE
## 6 Three-toed sloth Bradypus herbi TRUE
Ordenar por conservación como clave principal y género como clave menor:
msleep.with.dup.indicator2 <- mutate(msleep,duplicate.indicator = duplicated(conservation, genus)) %>%arrange(conservation,genus)
msleep.with.dup.indicator2
## # A tibble: 83 x 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>
Tanto la conservación como el género deben duplicarse para que el indicador duplicado se establezca en VERDADERO.
Crea un marco de datos de juguete:
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)
df <- data.frame(fruit,x,y,z,w)
df
## 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
df.show.single.dup <- mutate(df, duplicate.indicator = duplicated(fruit))
df.show.single.dup
## 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
DPLYR baja por las filas y observa los valores de la columna “fruta”. No puede detectar el primer duplicado porque aún no sabe si hay otro. Cuando ve “naranja” por segunda y tercera vez, establece la columna de indicador duplicado como “VERDADERO”para las filas que contienen el valor “naranja”. Si desea verificar varios campos, use mutate para combinarlos en un nuevo campo único antes de usar el indicador lógico duplicado (Verdadero / Falso)
\[\color{blue}{Eliminar~variables~usando~NULL}\]
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)
df
## 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
\[\color{blue}{Secuencia~de~codificación~preferida}\] John Mount, en su blog del 22 de septiembre de 2017 (www.rbloggers.com/my-advice-on dplyrmutate /), sugiere usar múltiples declaraciones de mutación para crear variables en lugar de ponerlas todas en un solo lugar. En un momento, esto marcó la diferencia al usar ciertos archivos de base de datos, pero posteriormente se corrigió. No obstante, el formato de mutación múltiple parece más seguro e intuitivo. A continuación, se muestran los métodos de codificación recomendados y no recomendados.
No recomendado pero funciona:
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 x 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)
Muestre las columnas seleccionadas para las primeras seis filas, incluidas las recién creadas.
newfield.flights[1:6,c(1:2,20:23)]
## # A tibble: 6 x 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
\[\color{blue}{Transmute:~mantener~solo~las~variables~creadas}\] Transmutar le 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)
df <- data.frame(fruit,x,y,z)
df #before transmute
## 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)
Después de transmute:
df
## new.variable
## 1 26
## 2 6
## 3 12
## 4 74
## 5 31
## 6 23
\[\color{blue}{Usar~Across~para~aplicar~una~función~sobre~varios~Columnas}\] Defina una función simple para duplicar el valor de un número:
double.it <- function(x) x*2
Tengo la base de datos original de “iris”
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
Mostrar un nuevo marco de datos de iris con valores duplicados para las columnas numéricas:
iris %>%
mutate(across(where(is.numeric), double.it)) %>%
head()
## 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
\[\color{blue}{Mutación~condicional~usando~case~when}\] Usando mutación condicional plus case_when, se 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)
df <- as.data.frame(rbind(row2,row3,row4,row5))
names(df) <- row1
df
## 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 <-df %>%
mutate(column.to.be.changed = 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 verdadero, entonces la última columna (column.to.be.changed) será un 2 o un 3.
Modificado:
new.df
## a b c d e f column.to.be.changed
## row2 1 1 1 6 6 1 3
## row3 3 4 4 6 4 4 3
## row4 4 6 25 5 5 2 3
## row5 5 3 6 3 3 6 2
\[\color{blue}{Seleccionar~para~elegir~variables/columnas}\] Para seeleccionar conservando solo las variables que incluye en la declaración de selección. La función de cambio de nombre, generalmente mencionada como una función hermana de select, no elimina ninguna variable. Tenga en cuenta que otros paquetes, como Zeilig, usan el comando select. Te arrancarás el pelo tratando de descifrar los mensajes de error de R si escribes código sintácticamente correcto basado en DPLYR / tidyverse pero has cargado algún otro paquete, que usa el mismo comando, por último. Hay dos formas de evitar esto: • Siempre ingrese “library (tidyverse)” en último lugar, después de que todos los demás paquetes hayan sido cargado. • Vincular explícitamente el comando al paquete: “dplyr∷select”. Mantener dentro Tenga en cuenta que DPLYR es parte de la colección tidyverse de coordinadas paquetes
\[\color{blue}{Eliminar~una~columna}\]
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) #before select
df
## 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
Para colocar un signo menos delante de cualquier variable que se desea eliminar. En este caso, la columna de frutas no se incluye en el nuevo marco de datos:
new.df.no.fruit <- dplyr::select(df, -fruit)
new.df.no.fruit #after select
## 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
\[\color{blue}{Eliminar~columnas~por~nombre~usando~starts~with~o~ends~with}\]
Utilice el comando de nombres para enumerar los nombres de las columnas en el marco de datos:
data("mtcars")
names(mtcars)
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
Elimine las columnas cuyos nombres comiencen con una “d”:
mtcars.no.col.names.start.with.d <- select(mtcars, -starts_with("d"))
names(mtcars.no.col.names.start.with.d)
## [1] "mpg" "cyl" "hp" "wt" "qsec" "vs" "am" "gear" "carb"
Elimine las columnas cuyos nombres terminen en “t”. En este caso, se eliminan “drat” y “wt”:
mtcars.no.col.names.ends.with <- select(mtcars,
- ends_with("t"))
names(mtcars.no.col.names.ends.with)
## [1] "mpg" "cyl" "disp" "hp" "qsec" "vs" "am" "gear" "carb"
\[\color{blue}{Reorganizar~el~orden~de~las~columnas}\]
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
## 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
Esta acción mueve la columna z a la izquierda de todo lo demás y, por lo tanto, 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.
\[\color{blue}{select~all~para~aplicar~una~función~a~todas~las~columnas}\] Utilice select_all para aplicar una función a todas las columnas. Antes los nombres de las columnas no están en mayúscula:
Se crea un nuevo dataframe
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)
top.3.states #antes: 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
Escriba en mayúsculas los nombres de las columnas, utilizando la función “toupper”:
new.top.3.states <- select_all(top.3.states, toupper)
new.top.3.states #after function "toupper" applied
## 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
\[\color{blue}{Seleccionar~columnas~con~la~función~de~pull}\] La función pull actúa de forma similar a la sintaxis de la dataframe$variable del marco de datos en R. Aísla una columna especificada. Puede especificar una columna de la izquierda (por ejemplo, la segunda columna a través de 2) o, utilizando un número negativo, una columna de la derecha
top.3.states <- data.frame(state, income, median.us, life.expectancy)
top.3.states #display dataframe values
## 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
Obtenga solo la primera columna de la izquierda, el estado:
pull.first.column <- pull(top.3.states,1)
pull.first.column
## [1] "Maryland" "Alaska" "New Jersey"
use un número negativo para sacar una columna de la derecha. -1 = columna más a la derecha:
pull.last.column <- pull(top.3.states,-1)
pull.last.column
## [1] 78.8 78.3 80.3
\[\color{blue}{Seleccionar~filas:~cualquier~variable~que~cumpla~alguna~condición}\] DPLYR muestra su potencia bruta en algunas de sus funciones menos utilizadas. Es posible que tenga un conjunto de datos del que desee saber, por ejemplo, si algo supera un determinado valor. El siguiente código filtra cualquier elemento del conjunto de datos superior a 200, en cualquier columna.
Número de filas en el marco de datos original:
nrow(mtcars)
## [1] 32
Muestre cualquier cosa, en cualquier lugar, más de 200:
mtcars.more.than.200 <- filter_all(mtcars, any_vars(. > 200))
nrow(mtcars.more.than.200)
## [1] 16
\[\color{blue}{Seleccionar~columnas:~Omitir~si~el~nombre~de~la~columna~contiene~caracteres~específicos}\] Seleccione columnas específicas más cualquier columna sin una “p”:
names(mtcars)
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
Nombres de las columnas del marco de datos después de la declaración de selección:
cars.with.no.p <- mtcars %>%
dplyr::select(-contains("p"))
names(cars.with.no.p)
## [1] "cyl" "drat" "wt" "qsec" "vs" "am" "gear" "carb"
No se incluye ningún nombre de columna con una “p” en ninguna parte en el nuevo dataframe.
\[\color{blue}{Seleccionar~usando~la~coincidencia~de~comodines}\] Muestre los nombres de las columnas del marco de datos integrado de mtcars:
names(mtcars)
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
Los nombres de columna seleccionados contienen los caracteres “pg” o “gea”. El símbolo de la tubería significa “OR”:
subset.mtcars <- select(mtcars,matches("pg|gea"))
names(subset.mtcars)
## [1] "mpg" "gear"
La función “matches” es más general que “contains” porque es una expresión regular y, por lo tanto, más flexible.
\[\color{blue}{Unión~a~la~izquierda~(más~común)}\] Unión izquierda: haga coincidir ambos archivos usando la tecla (by = “key”); mantenga todos los registros en el marco de datos izquierdo para cualquier registro coincidente en el marco de datos derecho y agregue datos a una nueva columna para crear el marco de datos de salida:
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
state.info.abb.area.name <- us.state.areas %>%
left_join(us.state.abbreviation.and.name, by = "state.abb")
head(state.info.abb.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
\[\color{blue}{Unir~internamente}\] La función de unión interna genera solo las filas en ambos marcos de datos cuando las claves son las mismas. Todas las demás filas se eliminan. En el siguiente ejemplo, team.info y school.and.team tienen a Sally, Tom y Alfonzo como claves comunes. Frieda y Bill se eliminan de la salida.
Crea el primer marco de datos:
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)
Crea un segundo dataframe:
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")
school.and.team
## names team.scores team.league school.grades
## 1 Sally 3 alpha A
## 2 Tom 5 beta B
## 3 Alfonzo 7 omicron B
Los datos aparecen en el dataframe de schol.and.team solo cuando los nombres coinciden exactamente.
\[\color{blue}{Anti-unirse}\] Salidas anti-unión x cuando no hay coincidencia con y. En el siguiente ejemplo, anti-join mantiene todos los valores de team.info sin coincidencia en school.info. Preste atención al orden en el que enumera los dos dataframes porque cambiarlos cambiará el resultado. “Names” es la clave en este caso. Un ejemplo de uso de anti-join es hacer coincidir una tabla de recursos humanos con una tabla de nómina en un sistema ERP. Por ejemplo, si coincide con el número de empleado y encuentra que un empleado está en el archivo de recursos humanos pero no en el archivo de nómina, puede asumir que el empleado aún no se ha configurado en la nómina.
Creamos primer el dataframe:
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)
team.info
## names team.scores team.league
## 1 Sally 3 alpha
## 2 Tom 5 beta
## 3 Frieda 2 gamma
## 4 Alfonzo 7 omicron
Creamos un segundo dataframe:
names <- c("Sally","Tom", "Bill", "Alfonzo")
school.grades <- c("A","B","C","B")
school.info <- data.frame(names, school.grades)
school.info
## names school.grades
## 1 Sally A
## 2 Tom B
## 3 Bill C
## 4 Alfonzo B
Los datos provienen de team.info, pero solo se muestran los nombres que NO coinciden con los datos de calificaciones. Frieda no tiene calificaciones:
team.info.but.no.grades <- anti_join(team.info, school.info,
by = "names")
team.info.but.no.grades
## names team.scores team.league
## 1 Frieda 2 gamma
\[\color{blue}{Unión~completa}\] Esta función de coincidencia mantiene todos los valores de ambos marcos de datos. Tenga en cuenta que las columnas donde no existen datos muestran valores de fila de NA. Por ejemplo, Bill está incluido en school.info pero no en team.info. Entonces aparecen su nombre y grado, pero no tiene puntaje de equipo ni liga de equipo.
Creamos el primer dataframe:
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)
Creamos el segundo dataframe:
names = c("Sally","Tom", "Bill", "Alfonzo")
school.grades = c("A","B","C","B")
school.info = data.frame(names, school.grades)
Cree un nuevo dataframe utilizando la combinación completa (tenga en cuenta que Frieda muestra school.grades como “NA”):
team.info.and.or.grades <- full_join(team.info, school.info, by = "names")
team.info.and.or.grades
## 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
\[\color{blue}{Semi-unión}\] Una semifusión mantiene todas las observaciones en el conjunto de datos1 que coinciden con el conjunto de dateset2. De nuevo, el orden de la lista del dataframe determina el resultado.
Utilice team.info y school.info del código anterior. Mantenga las filas de team.info que tienen una calificación:
team.info.with.grades <- semi_join(team.info, school.info)
## Joining, by = "names"
Tenga en cuenta en el código anterior que DPLYR es lo suficientemente inteligente como para comprender que “names” es una clave común. Frieda no tiene calificaciones, por lo que no se incluye en la salida:
team.info.with.grades
## names team.scores team.league
## 1 Sally 3 alpha
## 2 Tom 5 beta
## 3 Alfonzo 7 omicron
\[\color{blue}{Unión~derecha}\] La combinación derecha tiene el formato right_join (x, y, by = common_key). Devuelve todas las filas de y y columnas para los dataframe x. Donde no haya coincidencia en x y y, las columnas de x tendrán NAs. Si hay varias coincidencias entre x y y, todas las combinaciones se incluirán en la salida.
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
En este ejemplo, Alabama se reemplaza por “intencional mismatch”. Como resultado, falta en la salida. Sin embargo, se incluyen todas las columnas de ambos conjuntos de datos:
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,]
## state.abb state.area state.name
## 1 AK 589757 Alaska
## 2 AZ 113909 Arizona
## 3 AR 53104 Arkansas
\[\color{blue}{Slice}\] Slice proporciona una forma conveniente de incluir filas o rangos de filas específicas en sus conjuntos de datos. Piense en ello como una función de rango de filas.
Cargue el dataframe msleep del paquete ggplot2:
msleep <- ggplot2::msleep
nrow(msleep) #initially 83 rows
## [1] 83
msleep.only.first.5 <- slice(msleep, -6:-n())
Las filas 6 a 83 se eliminan. No es necesario que sepas cuántas filas existen en el marco de datos. La expresión “n (“)”es el número total de filas.
Ahora solo se conservan las cinco primeras filas:
nrow(msleep.only.first.5)
## [1] 5
msleep.20.rows <- msleep %>%
slice(20:39)
nrow(msleep.20.rows)
## [1] 20
Puede mostrar la diferencia entre el marco de datos original y cortado (o tibble) de la siguiente manera:
nrow(msleep) - nrow(msleep.20.rows)
## [1] 63
\[\color{blue}{Resumen}\] Resumir es mi función DPLYR favorita. Combinado con group_by, proporciona un tesoro de herramientas prácticas y rápidas para dimensionar datos (contar, sumar, desviación estándarm # y otras funciones) por una o más variables categóricas. Utilice el conjunto de datos integrado gehan del paquete MASS. Gehan incluye datos relacionados con la remisión de pacientes con leucemia. Desafortunadamente, tiene un conflicto de nombre de función con DPLYR, por lo que debe asegurarse de que DPLYR (o mejor aún, tidyverse) se cargue en último lugar.
Asegúrese de cargar tidyverse DESPUÉS de cargar MASS. De lo contrario, recibirá un mensaje de error.
El tiempo se basa en el tratamiento o ningún tratamiento con un medicamento en particular. Para estos datos, los tiempos de remisión más largos son un resultado positivo para el paciente. Esto es un poco torpe, pero hace que el conflicto MASS-tidyverse desaparezca:
library(MASS)
##
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
##
## select
data(gehan)
gehan2 <- gehan
library(tidyverse)
¿Cuántos pacientes participaron en el ensayo médico?
gehan2 %>% summarise( kount = n())
## kount
## 1 42
¿Cuál fue el recuento por tratamiento / sin tratamiento?
gehan2 %>%
group_by(treat) %>%
summarise(kount = n())
## # A tibble: 2 x 2
## treat kount
## <fct> <int>
## 1 6-MP 21
## 2 control 21
¿Cuáles son las estadísticas generales de tratamiento / no tratamiento?
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))
## # A tibble: 2 x 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>
Resumir se puede utilizar para encontrar el mínimo / máximo dentro del grupo “by”.
gehan2 %>%
group_by(treat) %>%
summarise(minimum.remission = min(time),
max.remission = max(time))
## # A tibble: 2 x 3
## treat minimum.remission max.remission
## <fct> <int> <int>
## 1 6-MP 6 35
## 2 control 1 23
\[\color{blue}{resumne~across}\] Utilice una encuesta de conjunto de datos incorporada, que muestra los datos de los estudiantes. Obtenga el promedio de cada columna numérica. Tenga en cuenta el uso de “across” para todas las columnas numéricas en esta sintaxis:
Library (MASA)
Obtenga las primeras diez filas y cópielas en un nuevo marco de datos:
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
Como un pequeño ahorro de tiempo, tenga en cuenta que head (), sin marco de datos especificado, usa el marco de datos o tibble en la tubería:
subset.survey %>%
na.omit() %>% #remove any NAs
group_by(Sex) %>%
summarise(across(where(is.numeric), mean,
.names = "mean_{col}")) %>%
head()
## # A tibble: 2 x 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
msleep es un conjunto de datos integrado del paquete ggplot2:
new.sleep <- msleep %>%
group_by(vore, order)
Utilice el sumarice para contar todas las combinaciones de órdenes:
s <- summarise(new.sleep, n())
## `summarise()` has grouped output by 'vore'. You can override using the `.groups` argument.
Si solo está interesado en los totales, extienda el uso de la tubería:
new.sleep.totals <- msleep %>%
group_by(vore, order) %>%
summarise(n())
## `summarise()` has grouped output by 'vore'. You can override using the `.groups` argument.
new.sleep.totals
## # A tibble: 32 x 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
\[\color{blue}{Recopilación:~convierta~varias~columnas~en~una}\] Gather convierte varias columnas en una columna. Para ilustrar, el siguiente ejemplo concentra tres columnas relacionadas con la fecha en una. 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
Ahora use recopilar para poner los tres años en una columna:
new.top.3.states <- top.3.states %>%
gather("2015", "2007", "1991", key = "year", value = "cases")
new.top.3.states
## 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
\[\color{blue}{Extensión:~consolidación~de~varias~filas~en~uno}\] A veces, los datos de la misma observación se encuentran en varias filas. Spread condensa esa información en una fila, lo que generalmente hace que los cálculos posteriores sean mucho más simples. El siguiente ejemplo se obtuvo del desbordamiento de pila.excelente sitio para la ayuda de R. Siempre me impresiona la calidad y la profundidad de las respuestas que se encuentran allí.
df_1 <- data_frame(Type = c("TypeA", "TypeA", "TypeB", "TypeB"),
Answer = c("Yes", "No", NA, "No"), n = 1:4)
## Warning: `data_frame()` was deprecated in tibble 1.1.0.
## Please use `tibble()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
df_1 #before
## # A tibble: 4 x 3
## Type Answer n
## <chr> <chr> <int>
## 1 TypeA Yes 1
## 2 TypeA No 2
## 3 TypeB <NA> 3
## 4 TypeB No 4
df_2 <- df_1 %>%
filter(!is.na(Answer)) %>%
spread(key=Answer, value=n)
Después de usar la propagación, las respuestas “NO” y “YES” están en columnas separadas, lo que facilita los resúmenes y otros análisis:
df_2 #after
## # A tibble: 2 x 3
## Type No Yes
## <chr> <int> <int>
## 1 TypeA 2 1
## 2 TypeB 4 NA
\[\color{blue}{Separar:~dividir~una~sola~columna~en~varias~columnas}\] La función separada divide una sola columna en dos o más 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)
teen.birth <- c("17//34.3//54.1", "29.0//42.9//66.0", "12.1//24.9//41.3")
teen.birth como columna tiene tres elementos de datos por fila, separados por un carácter especial (“//”). Antes de ejecutar la función separada, los años 2015, 2007 y 1991 se combinan en la columna de nacimiento de la adolescencia.
top.3.states <- data.frame(state, income, median.us,
life.expectancy,teen.birth)
top.3.states
## 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
Con la función separada, los datos de tres años agrupados en una columna se separan en una estructura mucho más conveniente de tres columnas:
top.3.states.separated.years <- top.3.states %>%
separate(teen.birth,
into = c("2015", "2007","1991"), sep = "//")
top.3.states.separated.years
## 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
\[\color{blue}{Resumen~de~funciones~útiles~de~DPLYR}\] DPLYR contiene una gran cantidad de funciones útiles para transformar sus datos en lo que necesita para resolver problemas analíticos. Los datos reales a menudo están plagados de valores perdidos, valores numéricamente válidos pero incorrectos, estructuras extrañas y muchas otras variaciones. Particularmente cuando trabaje con datos no estructurados, será de gran ayuda un conocimiento sólido de DPLYR, Stringr, Lubridate y expresiones regulares (a menudo abreviadas como RegEx). A continuación, se muestra un conjunto de herramientas útil que se puede usar junto con las cinco claves DPLYR funciones o, en algunos casos, autónomo. El manual DPLYR sobre CRAN tiene aún más profundidad (https://cran.r-project.org/web/packages/dplyr/dplyr.pdf) de lo que muestro aquí.
\[\color{blue}{Número~de~observaciones~(n)~utilizadas~en~varias~funciones~DPLYR}\] Un simple recuento de grupos es una herramienta para el uso diario. La función n se aplica a mutar, resumir y filtrar. El siguiente código, adaptado de la documentación del paquete DPLYR (al 10 de noviembre de 2018), combina varios usos de recuento de grupos en un comando de canalización.
\[\color{blue}{Recuentos~básicos}\]
m <- mutate(new.sleep, kount = n()) #new variable, kount added to extreme right
m[1:5,c(1:4,10:12)] #limit number of columns to fit on page
## # A tibble: 5 x 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
Filtrar por recuento de pedidos superiores a 14:
f <- filter(new.sleep, n() > 14)
f[1:5,c(1:4,10:11)]
## # A tibble: 5 x 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
\[\color{blue}{Funciones~Nth}\] Primera entrada:
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"
Ultima entrada:
last(salary.description)
## [1] "bring date seeds instead of flowers"
Tercera desde el final:
nth(salary.description, -3)
## [1] "Average"
Segundo elemento del vector:
nth(salary.description,2)
## [1] "Well to do"
\[\color{blue}{Contar~valores~distintos}\] Es útil determinar cuántos valores únicos existen en un vector. Utilice n_distinct () de la siguiente manera. Cree un vector de nueve elementos, algunos de los cuales no son únicos:
a.vector <- c(22,33,44,1,2,3,3,3,4)
original.length <- length(a.vector)
original.length
## [1] 9
Mostrar solo el número de elementos distintos (7):
distinct.a.vector <- n_distinct(a.vector)
distinct.a.vector
## [1] 7
test1 <- if_else(original.length == distinct.a.vector, "all values
unique","some duplicate values in vector")
test1
## [1] "some duplicate values in vector"
Ahora intente con ambos vectores que contengan valores únicos:
b.vector <- c(1,2,3,4,5,6)
length(b.vector)
## [1] 6
distinct.b.vector <- n_distinct(b.vector)
distinct.b.vector #show count (length) of distinct numbers
## [1] 6
test2 <- if_else(length(b.vector) == distinct.b.vector, "all values
unique", "duplicates")
test2
## [1] "all values \nunique"
\[\color{blue}{na-if}\] Puede establecer un valor de cálculo en un valor especificado si se calcula NA. Por ejemplo, la división por cero dará como resultado “inf” en el siguiente cálculo:
test <- c(100, 0, 999)
x <- 5000/test
x
## [1] 50.000000 Inf 5.005005
x <- 5000/na_if(test,0) # if any zero occurs in test,
x
## [1] 50.000000 NA 5.005005
class(x) #use class to show the type of variable
## [1] "numeric"
\[\color{blue}{Coalesce~para~reemplazar~los~valores~perdidos}\] Reemplace los valores faltantes con cero o algún otro valor usando la función de coalesce:
x <- c(33,4,11,NA,9)
x
## [1] 33 4 11 NA 9
x <- coalesce(x,0)
x
## [1] 33 4 11 0 9
\[\color{blue}{Funciones~de~clasificación}\] Los valores de un vector se pueden clasificar mediante una variedad de métodos. Las siguientes son algunas de las variaciones de DPLYR.
\[\color{blue}{Clasificación~a~través~de~índice}\] Este ejemplo muestra los números de índice del vector correspondiente a cada elemento. La clasificación muestra el 6 como el primer elemento, lo que significa que el sexto elemento de y, que es igual a 3, tiene el valor más bajo, ascendente. El valor de índice de 1, que se encuentra en el extremo derecho de rank1, corresponde al valor más alto del vector, 100.
y <- c(100,4,12,6,8,3)
rank1 <-row_number(y)
rank1
## [1] 6 2 5 3 4 1
y[rank1[1]] #lowest rank; in this case, rank1[1] points to # y[6] which is 3 (lowest)
## [1] 3
y[rank1[6]] #highest ranking number, in this case the first # number, 100
## [1] 100
\[\color{blue}{Rango~mínimo}\]
rank2 <- min_rank(y) #in this specific case (for y), gives same results as
#row_number
rank2
## [1] 6 2 5 3 4 1
\[\color{blue}{Rango~denso}\]
rank3 <- dense_rank(y)
rank3
## [1] 6 2 5 3 4 1
\[\color{blue}{Rango~de~porcentaje}\] El primer elemento de y está en el percentil 100; el segundo elemento de y está en el percentil 2; el último elemento de y está en el percentil 0:
rank4 <- percent_rank(y)
rank4
## [1] 1.0 0.2 0.8 0.4 0.6 0.0
\[\color{blue}{Función~de~distribución~acumulativa}\] Esta función muestra la proporción de todos los valores menores o iguales al rango actual:
y <- c(100,4,12,6,8,3)
rank5 <- cume_dist(y)
rank5
## [1] 1.0000000 0.3333333 0.8333333 0.5000000 0.6666667 0.1666667
Divida el vector de entrada en n depósitos:
rank6 = ntile(y, 3) #in this case, choose 3 buckets
rank6
## [1] 3 1 3 2 2 1
La función cuantil base R también tiene una salida fácil de leer:
test.vector <- c(2,22,33,44,77,89,99)
quantile(test.vector, prob = seq(0,1,length = 11),type = 5)
## 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
\[\color{blue}{Sampling}\] El muestreo sirve para muchos propósitos. En algunos casos, es posible que simplemente no tenga el tiempo o los recursos informáticos para procesar conjuntos de datos masivos. Con una computadora portátil estándar pero de alta potencia, es factible ejecutar entre 50 y 250 millones de registros, especialmente si vectoriza funciones en lugar de usar bucles de programación. El uso de tibbles en lugar de marcos de datos es otra forma de acelerar el procesamiento. Pero en algún momento, los conjuntos de datos muy grandes se vuelven difíciles de manejar y se requerirá un muestreo o un resumen intermedio (a menos que tenga recursos poderosos disponibles). El muestreo a menudo puede proporcionar un perfil de datos preciso y permitir visualizaciones razonablemente precisas. También es útil al desarrollar su sistema de análisis; no depure su lógica base arrastrando alrededor de 50M registros. Muestra primero.
Ejemplos:
Muestra aleatoriamente 5 filas de las 578 entradas de ChickWeight:
data("ChickWeight")
my.sample <- sample_n(ChickWeight, 5)
my.sample
## weight Time Chick Diet
## 1 98 10 30 2
## 2 40 0 25 2
## 3 160 18 6 1
## 4 84 6 50 4
## 5 66 8 24 2
Establezca un número de semilla cada vez que desee una muestra que otros puedan reproducir. De lo contrario, cada vez que se ejecuta la rutina, se pueden obtener resultados diferentes:
set.seed(833)
Muestrear con reemplazo = TRUE significa que puede obtener la misma fila o elemento más de una vez. Su elección de Verdadero o Falso 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:
my.sample <- sample_n(ChickWeight, 10, replace = TRUE)
my.sample
## 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
En algunos casos, el muestreo debe estar sesgado hacia algún elemento de datos de mayor impacto. Por ejemplo, si está verificando la exactitud de las facturas, es posible que desee ponderar las cantidades grandes en dólares más que las cantidades más pequeñas. Como resultado, es más probable que obtenga una factura de alto valor que una con un monto bajo en dólares. En la auditoría, esta práctica a veces se denomina “muestreo por unidad de dólar”.
En este ejemplo, es más probable que se seleccionen automóviles con más cilindros como parte de la muestra:
my.sample <- sample_n(mtcars, 12, weight = cyl)
my.sample[,1:5]
## 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
Utilice sample_frac para obtener una muestra igual a un porcentaje específico de las filas del dataframe:}
test1 <- sample_frac(ChickWeight, 0.02)
test1
## 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
En este ejemplo, group by identifica a los personajes de Star Wars por grupo de cabello, y luego se selecciona el 7% de los registros de cada grupo. Esto es útil cuando desea establecer un porcentaje de grupos cuyos tamaños varían.
by_hair_color <- starwars %>% group_by(hair_color)
my.sample <- sample_frac(by_hair_color, .07, replace = TRUE)
my.sample[,1:5]
## # A tibble: 5 x 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
El recuento y el recuento proporcionan recuentos básicos y recuentos por grupo.
row.kount.only <- ChickWeight %>% tally()
row.kount.only
## n
## 1 578
diet.kount <- ChickWeight %>% count(Diet)
diet.kount
## Diet n
## 1 1 220
## 2 2 120
## 3 3 120
## 4 4 118
\[\color{blue}{Funciones~misceláneas~de~DPLYR}\] \[\color{blue}{add-count~para~el~filtrado~grupal}\]
Este ejemplo de starwars está adaptado de la documentación oficial de DPLYR.7 Aquí, solo se muestran las especies que tienen un solo miembro. add_count es útil para el filtrado grupal. DPLYR no le proporciona una funcionalidad que no podría realizarse con baseR, Python, etc. Su gran valor es la eficiencia, la claridad y el ahorro de tiempo.
single.species.kount <- starwars %>%
add_count(species) %>%
filter(n == 1)
single.species.kount[,1:6]
## # A tibble: 29 x 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
\[\color{blue}{Renombrar}\]
mtcars <- rename(mtcars, spam_mpg = mpg)
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"
\[\color{blue}{case-when}\] case_when es particularmente útil dentro de mutate. 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"))
new.starwars
## # A tibble: 87 x 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 sin fin. Tanto MASS como DPLYR tienen la misma función, “seleccionar”. 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.