Selecione linhas de um quadro de dados com base em valores em um vetor

Eu tenho dados semelhantes a este:

dt <- structure(list(fct = structure(c(1L, 2L, 3L, 4L, 3L, 4L, 1L, 2L, 3L, 1L, 2L, 3L, 2L, 3L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"), X = c(2L, 4L, 3L, 2L, 5L, 4L, 7L, 2L, 9L, 1L, 4L, 2L, 5L, 4L, 2L)), .Names = c("fct", "X"), class = "data.frame", row.names = c(NA, -15L)) 

Eu quero selecionar linhas deste quadro de dados com base nos valores da variável fct . Por exemplo, se eu quiser selecionar linhas contendo “a” ou “c”, posso fazer isso:

 dt[dt$fct == 'a' | dt$fct == 'c', ] 

que produz

 1 a 2 3 c 3 5 c 5 7 a 7 9 c 9 10 a 1 12 c 2 14 c 4 

como esperado. Mas meus dados reais são mais complexos e, na verdade, quero selecionar linhas com base nos valores de um vetor, como

 vc <- c('a', 'c') 

Então eu tentei

 dt[dt$fct == vc, ] 

mas é claro que isso não funciona. Eu sei que eu poderia codificar algo para percorrer o vetor e extrair as linhas necessárias e anexá-las a um novo dataframe, mas eu esperava que houvesse uma maneira mais elegante.

Então, como eu posso filtrar / subconjunto meus dados com base no conteúdo do vetor vc ?

   

Dê uma olhada em ?"%in%" .

 dt[dt$fct %in% vc,] fct X 1 a 2 3 c 3 5 c 5 7 a 7 9 c 9 10 a 1 12 c 2 14 c 4 

Você também pode usar ?is.element :

 dt[is.element(dt$fct, vc),] 

Semelhante ao acima, usando o filter de dplyr :

 filter(df, fct %in% vc) 

Outra opção seria usar um data.table keyed:

 library(data.table) setDT(dt, key = 'fct')[J(vc)] # or: setDT(dt, key = 'fct')[.(vc)] 

o que resulta em:

  fct X 1: a 2 2: a 7 3: a 1 4: c 3 5: c 5 6: c 9 7: c 2 8: c 4 

O que isto faz:

  • setDT(dt, key = 'fct') transforma o data.frame em um data.table (que é uma forma aprimorada de um data.frame ) com a coluna fct definida como chave.
  • Em seguida, você pode apenas subconjuntos com o vetor vc com [J(vc)] .

NOTA: quando a chave é uma variável fator / caractere, você também pode usar setDT(dt, key = 'fct')[vc] mas isso não funcionará quando vc for um vetor numérico. Quando vc é um vetor numérico e não é empacotado em J() ou .() , vc funcionará como um índice de linha.

Uma explicação mais detalhada do conceito de chaves e subconjuntos pode ser encontrada no subconjunto baseado em vinhetas Keys e na pesquisa binária rápida .

Uma alternativa sugerida por @ Frank nos comentários:

 setDT(dt)[J(vc), on=.(fct)] 

Quando vc contém valores que não estão presentes em dt , você precisará adicionar nomatch = 0 :

 setDT(dt, key = 'fct')[J(vc), nomatch = 0] 

ou:

 setDT(dt)[J(vc), on=.(fct), nomatch = 0]