Mostrando entradas con la etiqueta %in%. Mostrar todas las entradas
Mostrando entradas con la etiqueta %in%. Mostrar todas las entradas

2021-03-04

Cómo filtrar múltiples valores en una columna en R

Problema

Queremos filtrar múltiples valores en una columna en R. En nuestro ejemplo, queremos filtrar las filas que contengan la cadena de texto Tom o Lynn en la columna name.

Ejemplo

  days  name
1   88  Lynn
2   11   Tom
3    2 Chris
4    5  Lisa
5   22  Kyla
6    1   Tom
7  222  Lynn
8    2  Lynn
df <-
  data.frame(
    days = c(88, 11, 2, 5, 22, 1, 222, 2),
    name = c("Lynn", "Tom", "Chris", "Lisa", "Kyla", "Tom", "Lynn", "Lynn")
  ) 

Solución

  • Base package
  • df[df$name %in% c("Tom", "Lynn"), ] # or
    target <- c("Tom", "Lynn")
    df[df$name %in% target, ]
    
      days name
    1   88 Lynn
    2   11  Tom
    6    1  Tom
    7  222 Lynn
    8    2 Lynn
    
  • dplyr
  • library(dplyr)
    filter(df, name %in% c("Tom", "Lynn")) # or
    target <- c("Tom", "Lynn")
    filter(df, name %in% target)
    
  • data.table
  • library(data.table)
    DT <- data.table(df)
    DT[name %in% target]
    
  • sqldf
  • library(sqldf)
    # Dos alternativas:
    sqldf('SELECT *
          FROM df 
          WHERE name = "Tom" OR name = "Lynn"')
    sqldf('SELECT *
          FROM df 
          WHERE name IN ("Tom", "Lynn")')
    

    Entradas relacionadas

    Referencias

    How to filter multiple values on a column in R

    Problem

    We want to filter multiple values on a column in R. In our example, we want to subset the rows containing the string Tom or Lynn for the column name.

    Example

      days  name
    1   88  Lynn
    2   11   Tom
    3    2 Chris
    4    5  Lisa
    5   22  Kyla
    6    1   Tom
    7  222  Lynn
    8    2  Lynn
    
    df <-
      data.frame(
        days = c(88, 11, 2, 5, 22, 1, 222, 2),
        name = c("Lynn", "Tom", "Chris", "Lisa", "Kyla", "Tom", "Lynn", "Lynn")
      ) 
    

    Solution

  • Base package
  • df[df$name %in% c("Tom", "Lynn"), ] # or
    target <- c("Tom", "Lynn")
    df[df$name %in% target, ]
    
      days name
    1   88 Lynn
    2   11  Tom
    6    1  Tom
    7  222 Lynn
    8    2 Lynn
    
  • dplyr
  • library(dplyr)
    filter(df, name %in% c("Tom", "Lynn")) # or
    target <- c("Tom", "Lynn")
    filter(df, name %in% target)
    
  • data.table
  • library(data.table)
    DT <- data.table(df)
    DT[name %in% target]
    
  • sqldf
  • library(sqldf)
    # Two alternatives:
    sqldf('SELECT *
          FROM df 
          WHERE name = "Tom" OR name = "Lynn"')
    sqldf('SELECT *
          FROM df 
          WHERE name IN ("Tom", "Lynn")')
    

    Related posts

    References

    2016-05-11

    Muestra aleatoria basada en una columna en R

    Title

    Problema

    Queremos extraer del siguiente data frame una muestra aleatoria basada en la columna id, de manera que seleccionemos aleatoriamente dos ids y extraigamos todas las filas asociadas a los mismos. Por ejemplo, si seleccionamos aleatoriamente los ids 1 y 2, el resultado debería incluir las tres primeras filas.

      id     date      date2
    1  1 23-01-08 2008-01-23
    2  1 01-11-07 2007-11-01
    3  2 30-11-07 2007-11-30
    4  3 17-12-07 2007-12-17
    5  3 12-12-08 2008-12-12
    
    id<-c(1,1,2,3,3)
    date<-c("23-01-08","01-11-07","30-11-07","17-12-07","12-12-08")
    df<-data.frame(id,date)
    df$date2<-as.Date(as.character(df$date), format = "%d-%m-%y")
    

    Soluciones

  • Paquete base
  • a <- sample(unique(df$id), 2)
    subset(df, id %in% a)
    
  • sqldf
  • library(sqldf)
    a <- sqldf("SELECT DISTINCT id FROM df  ORDER BY RANDOM(*) LIMIT 2")
    sqldf("SELECT * FROM df WHERE id IN a")
    
      id     date      date2
    1  1 23-01-08 2008-01-23
    2  1 01-11-07 2007-11-01
    3  2 30-11-07 2007-11-30
    

    Entradas relacionadas

    Referencias

    2016-02-10

    Seleccionar con sqldf un subconjunto de filas de una columna en un data frame diferente

    Title

    Problema

    Supongamos que tenemos los siguientes data frames.

    #A
      a1  a2
    1  1 101
    2  2 102
    3  3 103
    4  4 104
    
    #B
      a1  a2
    1  1 101
    2  2 102
    3  3 103
    4  4 104
    
    A <-  data.frame(a1 = c(1:4), a2 = c(101:104))
    B <-  data.frame(b1 = c(1:2), b2 = c(55,56))
    
    Deseamos obtener el siguiente subconjunto de filas del data frame A, en el que la columna A$a1 contenga los elementos de la columna B%b1 del data frame B. Pero en lugar del paquete base, como hacemos a continuación, queremos emplear el paquete sqldf.

    A[A$a1 %in% B$b1, ]
    

     a1  a2
    1  1 101
    2  2 102
    

    Solución

    Usamos la función paste dos veces. Para concatenar los elementos del vector B$b1 separado por comas, y después para concatenar la cadena de texto deseada: [1] "select * from A where a1 in( 1,2 )"

    library(sqldf)
    sqldf(paste("select * from A where a1 in(", paste(B$b1, collapse = ","), ")"))
    
    Otras dos alternativas propuestas por G. Grothendieck son:

    # 1
    fn$sqldf(" select * from A where a1 in ( `toString(B$b1)` ) ") 
    # 2
    sqldf("select A.* from A join B on A.a1 = B.b1")
    

    Resultado

     a1  a2
    1  1 101
    2  2 102
    

    Referencias

    2015-11-05

    Descartar variables de un data frame por su nombre

    Title

    Problema

    Deseamos excluir variables de un data frame de acuerdo a su nombre. En nuestro ejemplo usamos el data frame iris, y queremos descartar las variables Sepal.Length y Petal.Width.

    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
    

    Soluciones

    Hay múltiples opciones.

  • Paquete base
  • # Opción 1
    iris[, -which(names(iris) %in% c("Sepal.Length", "Petal.Width"))]
    # Opción 2
    iris[ , !names(iris) %in% c("Sepal.Length","Petal.Width")]
    # Opción 3
    subset(iris, select = -c(Sepal.Length, Petal.Width)) 
    
  • dplyr
  • library(dplyr)
    iris %>% select(-c(Sepal.Length, Petal.Width))
    
  • data.table
  • library(data.table)
    DT = as.data.table(iris)
    DT[ , !names(DT) %in% c("Sepal.Length", "Petal.Width"), with = FALSE]
    # Otra opción
    subset(DT, select=-c(Sepal.Length, Petal.Width)) 
    

    Resultado

    Las tres variables restantes. Solamente mostramos las 6 primeras filas

      Sepal.Width Petal.Length Species
    1         3.5          1.4  setosa
    2         3.0          1.4  setosa
    3         3.2          1.3  setosa
    4         3.1          1.5  setosa
    5         3.6          1.4  setosa
    6         3.9          1.7  setosa
    

    Notas

    Hay diferencias sutiles entre la primera opción con el paquete base -which y la segunda con la función !. Si con -which especificamos nombres que no encuentra en el data frame devolverá un data frame vacío con cero columnas. Mientras que si sucede lo mismo con !, devolverá el data frame original sin modificar.

    La sintaxis con dplyr es bastante sencilla. Con data.table es muy similar a las utilizadas con el paquete base. No obstante, es necesario especificar el argumento with = FALSE o devolverá un vector lógico. También podemos emplear con data.table la función subset.

    Entradas relacionadas

    Referencias

    2015-10-08

    Comparar dos vectores en R: elementos comunes y únicos

    Title

    Problema

    Deseamos comparar dos vectores en R y obtener los elemenos comunes y únicos de ambos.

    Datos

    # Dos vectores
    [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
    [1] "f" "g" "h" "i" "j" "k" "l" "m" "n" "o"
    
    a <- letters[seq(from = 1, to = 10)]
    b < -letters[seq(from = 6, to = 15)]
    

    Soluciones

  • Elementos comunes
  • # Múltiples opciones
    intersect(a, b)
    b[b %in% a]
    a[a %in% b]
    
    [1] "f" "g" "h" "i" "j"
  • Elementos únicos de a
  • setdiff(a, b)
    a[!a %in% b]
    a[b %in% a]
    
    [1] "a" "b" "c" "d" "e"
  • Elementos únicos de b
  • setdiff(b, a)
    b[!b %in% a]
    b[a %in% b]
    
    [1] "k" "l" "m" "n" "o"

    Notas

    Merece la pena señalar que intersect y setdiff descartarán los valores duplicados en los argumentos. Mientras que %in% conservará los duplicados. Por lo que si tuviéramos duplicados en loos vectores obtendríamos diferentes resultados. Por ejemplo, introduciendo un elemento duplicado 'a' en el vector a.

    a <- c(a, "a")
    [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "a"
  • setdiff descarta los duplicados
  • setdiff(a, b)
    [1] "a" "b" "c" "d" "e"
  • El operador "[]" con %in% los conserva
  • a[!a %in% b]
    [1] "a" "b" "c" "d" "e" "a"

    Entradas relacionadas

    Referencias

    Nube de datos