Indexación y filtrado en R

Vamos a trabajar con tablas en R para aprender como indexarlas y de esa forma encontrar la información que nos interesa. Para ello vamos a utilizar funciones básicas en R, sin necesidad de instalar paquetes extras.

Cargamos el dataset restaurant a modo de ejemplo. Puede encontrar ese dataset en la carpeta data del laboratorio 1 (L1)

restaurant <- read.csv("../data/restaurant.csv")
print(restaurant)
##    Alternativa Bar Vier.Sab Hambriento Clientes Precio Lloviendo Reserva
## 1           Si  No       No         Si  Algunos    $$$        No      Si
## 2           Si  No       No         Si    Lleno      $        No      No
## 3           No  Si       No         No  Algunos      $        No      No
## 4           Si  No       Si         Si    Lleno      $        Si      No
## 5           Si  No       Si         No    Lleno    $$$        No      Si
## 6           No  Si       No         Si  Algunos     $$        Si      Si
## 7           No  Si       No         No  Ninguno      $        Si      No
## 8           No  No       No         Si  Algunos     $$        Si      Si
## 9           No  Si       Si         No    Lleno      $        Si      No
## 10          Si  Si       Si         Si    Lleno    $$$        No      Si
## 11          No  No       No         No  Ninguno      $        No      No
## 12          Si  Si       Si         Si    Lleno      $        No      No
##         Tipo TpoEspera Esperar
## 1    Frances      0-10       1
## 2  Tailandes     30-60       0
## 3    Hamburg      0-10       1
## 4  Tailandes     10-30       1
## 5    Frances       >60       0
## 6   Italiano      0-10       1
## 7    Hamburg      0-10       0
## 8  Tailandes      0-10       1
## 9    Hamburg       >60       0
## 10  Italiano     10-30       0
## 11 Tailandes      0-10       0
## 12   Hamburg     30-60       1

Un resumen del dataset

summary(restaurant)
##  Alternativa Bar    Vier.Sab Hambriento    Clientes Precio  Lloviendo
##  No:6        No:6   No:7     No:5       Algunos:4   $  :7   No:7     
##  Si:6        Si:6   Si:5     Si:7       Lleno  :6   $$ :2   Si:5     
##                                         Ninguno:2   $$$:3            
##                                                                      
##                                                                      
##                                                                      
##  Reserva        Tipo   TpoEspera    Esperar   
##  No:7    Frances  :2   0-10 :6   Min.   :0.0  
##  Si:5    Hamburg  :4   10-30:2   1st Qu.:0.0  
##          Italiano :2   30-60:2   Median :0.5  
##          Tailandes:4   >60  :2   Mean   :0.5  
##                                  3rd Qu.:1.0  
##                                  Max.   :1.0

Observamos los nombres de sus filas y columnas

dimnames(restaurant)
## [[1]]
##  [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12"
## 
## [[2]]
##  [1] "Alternativa" "Bar"         "Vier.Sab"    "Hambriento"  "Clientes"   
##  [6] "Precio"      "Lloviendo"   "Reserva"     "Tipo"        "TpoEspera"  
## [11] "Esperar"

Nro total de filas

nrow(restaurant)
## [1] 12

Nro total de columnas

ncol(restaurant)
## [1] 11

Podemos acceder a las columnas por su nombre o ubicación (se comienza a indexar desde 1 hasta el tamaño máximo de fila/columna).

Ejemplos:

  1. Obtener el valor de una fila y columna específica
columna_nro <- 2
fila_nro <-3
print(restaurant[fila_nro,columna_nro])
## [1] Si
## Levels: No Si
  1. Mostrar un rango de filas y columnas
print(restaurant[1:5,1:3])
##   Alternativa Bar Vier.Sab
## 1          Si  No       No
## 2          Si  No       No
## 3          No  Si       No
## 4          Si  No       Si
## 5          Si  No       Si

Observe que el primer lugar antes de la coma es para indexar filas y luego de la coma para columnas.

  1. Cuantas veces se decide esperar
sum(restaurant[,"Esperar"])
## [1] 6
  1. Obtener los valores unicos del tipo de restaurante
unique(restaurant$Tipo)
## [1] Frances   Tailandes Hamburg   Italiano 
## Levels: Frances Hamburg Italiano Tailandes
  1. Obtener el total de veces que Alternativa es igual a Si
sum(restaurant[,1]=="Si")
## [1] 6

Si observamos el ejemplo anterior, vemos que restaurant[,1]==“Si”` nos regresa un vector de valores lógicos (TRUE / FALSE). Si revisa en la ayuda de R (tipeando ?sum en la consola) a TRUE lo cuenta como 1 y a FALSE como 0

print(restaurant[,1]=="Si")
##  [1]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
## [12]  TRUE
sum(restaurant[,1]=="Si")
## [1] 6

Filtrar filas

Las filas pueden ser accedidas por su indice, nombre o “índice lógico”, al igual que las columnas.

print(restaurant["4",])
##   Alternativa Bar Vier.Sab Hambriento Clientes Precio Lloviendo Reserva
## 4          Si  No       Si         Si    Lleno      $        Si      No
##        Tipo TpoEspera Esperar
## 4 Tailandes     10-30       1
print(restaurant[5,])
##   Alternativa Bar Vier.Sab Hambriento Clientes Precio Lloviendo Reserva
## 5          Si  No       Si         No    Lleno    $$$        No      Si
##      Tipo TpoEspera Esperar
## 5 Frances       >60       0

Note que en las siguientes sentencias solo me regresa las primeras 4 filas, porque indexo con val, un vector de valores logicos.

val <- c(TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE)
restaurant[val,]
##   Alternativa Bar Vier.Sab Hambriento Clientes Precio Lloviendo Reserva
## 1          Si  No       No         Si  Algunos    $$$        No      Si
## 2          Si  No       No         Si    Lleno      $        No      No
## 3          No  Si       No         No  Algunos      $        No      No
## 4          Si  No       Si         Si    Lleno      $        Si      No
##        Tipo TpoEspera Esperar
## 1   Frances      0-10       1
## 2 Tailandes     30-60       0
## 3   Hamburg      0-10       1
## 4 Tailandes     10-30       1

Filtrar usando sentencias lógicas

Si quiero filtrar la columna Clientes donde Esperar sea 1 (que si prefieren esperar), puedo usar variables que guarden el valor que me interesa obtener/filtrar.

atributo <- "Clientes"
target <- "Esperar"
label <- 1

Filtramos usando lo siguiente

restaurant[restaurant[,target]==label,atributo]
## [1] Algunos Algunos Lleno   Algunos Algunos Lleno  
## Levels: Algunos Lleno Ninguno

Note que restaurant[,target]==label regresa un vector con valores TRUE y FALSE

print(restaurant[,target]==label)
##  [1]  TRUE FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE
## [12]  TRUE

Luego si quiero contar cuantas veces aparece el valor del atributo, guardo los datos en una variable c (para hacer legible el ejemplo) y usamos la función table.

c <- restaurant[restaurant[,target]==label,atributo]
print(c)
## [1] Algunos Algunos Lleno   Algunos Algunos Lleno  
## Levels: Algunos Lleno Ninguno
table(c)
## c
## Algunos   Lleno Ninguno 
##       4       2       0

Para obtener la cantidad en tipo numérico de uno de los atributos

table(c)["Lleno"]
## Lleno 
##     2
is.numeric(table(c)["Lleno"]) # acceder al valor numérico de Lleno
## [1] TRUE

Puedo calcular las proporciones (cantidad de elementos sobre su total)

print(table(c)/sum(table(c)))
## c
##   Algunos     Lleno   Ninguno 
## 0.6666667 0.3333333 0.0000000

Indexar o filtrar por más de una condición

Ejemplo, filtrar con clientes=Algunos y Esperar=1

restaurant[(restaurant[,target]==label) & (restaurant[,atributo]=="Algunos"),]
##   Alternativa Bar Vier.Sab Hambriento Clientes Precio Lloviendo Reserva
## 1          Si  No       No         Si  Algunos    $$$        No      Si
## 3          No  Si       No         No  Algunos      $        No      No
## 6          No  Si       No         Si  Algunos     $$        Si      Si
## 8          No  No       No         Si  Algunos     $$        Si      Si
##        Tipo TpoEspera Esperar
## 1   Frances      0-10       1
## 3   Hamburg      0-10       1
## 6  Italiano      0-10       1
## 8 Tailandes      0-10       1

Puedo crear varias condiciones, agregamos un filtro por tipo de restaurant

condicion <- (restaurant[,target]==label) & (restaurant[,atributo]=="Algunos") & (restaurant[,"Tipo"] %in% c("Frances","Italiano"))

restaurant[condicion,]
##   Alternativa Bar Vier.Sab Hambriento Clientes Precio Lloviendo Reserva
## 1          Si  No       No         Si  Algunos    $$$        No      Si
## 6          No  Si       No         Si  Algunos     $$        Si      Si
##       Tipo TpoEspera Esperar
## 1  Frances      0-10       1
## 6 Italiano      0-10       1

Cuantos cumplen que Clientes sea igual a “Algunos” y “Esperar” = 1

nrow(restaurant[(restaurant[,target]==label) & (restaurant[,atributo]=="Algunos"),] )
## [1] 4

Asi como usamos el operado logico AND & se puede usar OR | o el NOT !. Para ello consulte este link, o este u otros de su interés