Filtrar linhas data.frame por uma condição lógica

155

Eu quero filtrar linhas de uma com data.framebase em uma condição lógica. Vamos supor que eu tenha um quadro de dados como

   expr_value     cell_type
1    5.345618 bj fibroblast
2    5.195871 bj fibroblast
3    5.247274 bj fibroblast
4    5.929771          hesc
5    5.873096          hesc
6    5.665857          hesc
7    6.791656          hips
8    7.133673          hips
9    7.574058          hips
10   7.208041          hips
11   7.402100          hips
12   7.167792          hips
13   7.156971          hips
14   7.197543          hips
15   7.035404          hips
16   7.269474          hips
17   6.715059          hips
18   7.434339          hips
19   6.997586          hips
20   7.619770          hips
21   7.490749          hips

O que eu quero é obter um novo quadro de dados com a mesma aparência, mas que tenha apenas os dados para um cell_type. Por exemplo, subconjunto / seleção de linhas que contém o tipo de célula "hesc":

   expr_value     cell_type
1    5.929771          hesc
2    5.873096          hesc
3    5.665857          hesc

Ou o tipo de célula "fibroblasto bj" ou "hesc":

   expr_value     cell_type
1    5.345618 bj fibroblast
2    5.195871 bj fibroblast
3    5.247274 bj fibroblast
4    5.929771          hesc
5    5.873096          hesc
6    5.665857          hesc

Existe alguma maneira fácil de fazer isso?

Eu tentei:

expr[expr[2] == 'hesc']
# [1] "5.929771" "5.873096" "5.665857" "hesc"     "hesc"     "hesc"    

se o quadro de dados original for chamado "expr", mas fornecer os resultados no formato errado, como você pode ver.

lhahne
fonte

Respostas:

210

Para selecionar linhas de acordo com um 'cell_type' (por exemplo, 'hesc'), use ==:

expr[expr$cell_type == "hesc", ]

Para selecionar linhas de acordo com dois ou mais 'cell_type' diferentes (por exemplo, 'hesc' ou 'bj fibroblast'), use %in%:

expr[expr$cell_type %in% c("hesc", "bj fibroblast"), ]
learnr
fonte
28
Esteja ciente de que a ==função selecionará todos os registros de NA e "hesc", enquanto %in%não.
Matt Parker
Gostaria de saber se isso funciona agora? Não consegui subconectar o quadro de dados com base nas condições dessa maneira.
Sumanth Lazarus
85

Use subset(para uso interativo)

subset(expr, cell_type == "hesc")
subset(expr, cell_type %in% c("bj fibroblast", "hesc"))

ou melhor dplyr::filter()

filter(expr, cell_type %in% c("bj fibroblast", "hesc"))
rcs
fonte
37
Cuidado! A documentação de subsettem um grande aviso: "Esta é uma função de conveniência destinada ao uso interativamente. Para programar, é melhor usar as funções de subconjunto padrão como [e, em particular, a avaliação não padronizada do subconjunto de argumentos pode ter conseqüências imprevistas. . "
Aleksandar Dimitrov
33

O motivo expr[expr[2] == 'hesc']não funciona é que, para um quadro de dados, x[y]seleciona colunas, não linhas. Se você deseja selecionar linhas, mude para a sintaxe x[y,]:

> expr[expr[2] == 'hesc',]
  expr_value cell_type
4   5.929771      hesc
5   5.873096      hesc
6   5.665857      hesc
Ken Williams
fonte
Isso também pegará todos os NAregistros! Portanto, não aplicável. A razão pela qual isso parecia ser verdade resultou do fato de o expr dataframe não ter NAna coluna filtrada. Se houver NA, seu caminho não será aplicável, como eu disse antes.
Erdogan CEVHER
26

Você pode usar o dplyrpacote:

library(dplyr)
filter(expr, cell_type == "hesc")
filter(expr, cell_type == "hesc" | cell_type == "bj fibroblast")
nathaneastwood
fonte
5

Parece que ninguém incluiu a função que. Também pode ser útil para filtrar.

expr[which(expr$cell == 'hesc'),]

Isso também manipulará os NAs e os eliminará do quadro de dados resultante.

Executando isso em um dataframe 9840 por 24 50000 vezes, parece que o método tem um tempo de execução 60% mais rápido que o método% in%.

eigenfoo
fonte
4

Eu estava trabalhando em um dataframe e não tendo sorte com as respostas fornecidas, ele sempre retornava 0 linhas, então encontrei e usei o grepl:

df = df[grepl("downlink",df$Transmit.direction),]

Que basicamente aparou meu quadro de dados apenas nas linhas que continham "downlink" na coluna Direção de transmissão. PS Se alguém puder adivinhar por que não estou vendo o comportamento esperado, deixe um comentário.

Especificamente para a pergunta original:

expr[grepl("hesc",expr$cell_type),]

expr[grepl("bj fibroblast|hesc",expr$cell_type),]
Justin Harbour
fonte
3

Às vezes, a coluna que você deseja filtrar pode aparecer em uma posição diferente do índice da coluna 2 ou ter um nome de variável.

Nesse caso, você pode simplesmente referir o nome da coluna que deseja filtrar como:

columnNameToFilter = "cell_type"
expr[expr[[columnNameToFilter]] == "hesc", ]
Daniel Bonetti
fonte
Isso também pegará todos os NAregistros! Portanto, não aplicável.
Erdogan CEVHER
0

podemos usar a biblioteca data.table

  library(data.table)
  expr <- data.table(expr)
  expr[cell_type == "hesc"]
  expr[cell_type %in% c("hesc","fibroblast")]

ou filtre usando o %like%operador para correspondência de padrões

 expr[cell_type %like% "hesc"|cell_type %like% "fibroblast"]
Varn K
fonte
0

Isso funcionou como mágica para mim.

celltype_hesc_bool = expr['cell_type'] == 'hesc'

expr_celltype_hesc = expr[celltype_hesc]

Verifique esta postagem do blog

DKMDebugin
fonte