Menu

Filtrar e Criar Subconjuntos de Dados no R (subset, [ ], dplyr filter)

Todas as formas de manter as linhas e colunas que você quer: máscaras lógicas com colchetes, o atalho subset(), %in%, armadilhas de NA e o filter() e select() do dplyr.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Filtrando Linhas: A Máscara Lógica

Para filtrar um data frame no R, coloque uma condição na posição das linhas dentro dos colchetes: df[condition, ]. A condição é avaliada como um vetor de TRUE/FALSE, um por linha, e o R mantém as linhas TRUE:

Leia scores[scores$score > 80, ] de dentro para fora: scores$score > 80 produz TRUE FALSE TRUE TRUE FALSE, e os colchetes mantêm as linhas 1, 3 e 4. A vírgula final não é opcional. Colchetes em um data frame recebem [linhas, colunas]; deixar o espaço das colunas vazio significa "todas as colunas". Esqueça a vírgula e você estará indexando colunas em vez de linhas - um dos erros de iniciante mais comuns do R.

Repare que os números de linha impressos são 1 3 4, não 1 2 3 - a filtragem mantém os rótulos originais das linhas. Inofensivo, mas surpreende as pessoas.

Múltiplas Condições: & e | (Não &&)

Combine condições com & (E) e | (OU). Cada condição precisa da sua própria comparação completa:

A armadilha: o R também tem && e ||, e eles não são intercambiáveis com & e | aqui. As formas duplas funcionam com valores únicos (elas existem para condições de if); ao receber colunas inteiras, o R moderno (4.3+) para com um erro como 'length = 5' in coercion to 'logical(1)', e o R mais antigo comparava silenciosamente apenas a primeira linha - o que é possivelmente pior. Dentro de colchetes, sempre o & e o | simples. A documentação de operadores cobre a distinção por completo.

%in%: Comparar com um Conjunto de Valores

Quando uma coluna deve corresponder a qualquer um de vários valores, não encadeie == com | - use %in%:

x %in% set retorna TRUE sempre que x é um dos valores em set. Ele se lê melhor do que status == "pending" | status == "shipped", escala para qualquer quantidade de valores e nega de forma limpa: !(orders$status %in% c("refunded")).

Selecionando Colunas

O espaço das colunas nos colchetes aceita nomes ou posições:

Duas observações. Selecionar por nome sobrevive à reordenação de colunas; selecionar por posição (scores[, c(1, 3)]) quebra no dia em que alguém insere uma coluna. E pedir uma única coluna retorna um vetor simples, não um data frame - é por isso que o segundo print() mostra 91 88 sem uma tabela em volta. Quando você precisar manter o formato de data frame, adicione drop = FALSE: scores[, "score", drop = FALSE].

subset(): O Atalho Amigável do R Base

O R base traz um invólucro que faz linhas e colunas em uma única chamada legível - sem $, sem contabilidade de vírgulas:

Dentro de subset() você escreve nomes de colunas sem prefixo (score, não scores$score) - ele os avalia contra o data frame. Isso se chama avaliação não padrão, e vem com uma ressalva documentada: ela resolve nomes em tempo de execução de formas que se comportam mal dentro das suas próprias funções (uma variável chamada score na sua função pode ser sombreada por uma coluna chamada score). A regra prática, direto de ?subset: ótimo no uso interativo, evite em programação - use indexação por colchetes nesse caso.

A Armadilha do NA

Uma comparação com NA produz NA, não FALSE - e a filtragem por colchetes mantém as linhas com máscara NA como linhas cheias de NA:

O primeiro resultado contém uma linha lixo de NAs porque a condição da linha 2 não era nem TRUE nem FALSE. A correção é exigir !is.na() explicitamente. Tanto subset() quanto o filter() do dplyr descartam silenciosamente as linhas com condição NA - conveniente, mas saiba que isso está acontecendo. A documentação de valores ausentes explica por que o NA se espalha assim.

O Jeito dplyr: filter() e select()

O pacote dplyr divide o trabalho em dois verbos - filter() para linhas, select() para colunas - com nomes de colunas sem prefixo e sem repetição de df$ (estático; o sandbox executa apenas R base):

library(dplyr)

scores |> filter(score > 80)
scores |> filter(score > 80, team == "red")     # comma = AND
scores |> filter(status %in% c("pending", "shipped"))
scores |> select(name, score)
scores |> filter(team == "red") |> select(name, score)

filter() descarta automaticamente as linhas com condição NA e sempre retorna um data frame (nunca um vetor solto), o que elimina as duas pegadinhas do R base acima. O custo é uma dependência de pacote e as mesmas ressalvas de avaliação não padrão do subset() - veja a introdução ao dplyr para o tour completo dos verbos.

O Que Você Leva Daqui

  • df[condition, ] é o idioma fundamental - e a vírgula é obrigatória.
  • Combine condições com & e | simples; && gera erro com vetores.
  • %in% supera cadeias de == para comparar com um conjunto de valores.
  • Selecione colunas por nome e lembre-se de que colunas únicas viram vetores, a menos que use drop = FALSE.
  • subset() é o atalho agradável para uso interativo; os colchetes são a opção programável.
  • Comparações com NA produzem linhas fantasma nos colchetes - proteja-se com !is.na().

A seguir: adicionar e transformar colunas - df$new <- ..., ifelse() e o mutate() do dplyr.

Perguntas frequentes

Como filtro as linhas de um data frame no R?

Coloque uma condição lógica na posição das linhas dentro dos colchetes: df[df$score > 80, ]. A condição produz um vetor de TRUE/FALSE, e o R mantém as linhas TRUE. A vírgula importa - ela separa o filtro de linhas do filtro (vazio) de colunas. subset(df, score > 80) faz o mesmo com menos digitação.

Como filtro com múltiplas condições no R?

Combine as condições com & (E) e | (OU): df[df$score > 80 & df$team == "red", ]. Use o & simples, não && - a forma dupla funciona apenas com valores únicos e gera erro com vetores no R moderno.

Qual é a diferença entre subset() e filtragem com colchetes no R?

Elas mantêm as mesmas linhas, com duas diferenças: subset() descarta silenciosamente as linhas em que a condição é NA (os colchetes as mantêm como linhas preenchidas com NA), e subset() usa avaliação não padrão - você escreve nomes de colunas sem prefixo, o que é conveniente no uso interativo mas pouco confiável dentro das suas próprias funções.

Como filtro linhas em que uma coluna corresponde a uma lista de valores?

Use %in%: df[df$team %in% c("red", "blue"), ] mantém as linhas cujo team é qualquer um dos valores listados. Ele substitui uma cadeia de comparações == unidas por | e, diferentemente de ==, nunca retorna NA.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR