Selecionar linhas de uma matriz que atendem a uma condição

144

Em R com uma matriz:

     one two three four
 [1,]   1   6    11   16
 [2,]   2   7    12   17
 [3,]   3   8    11   18
 [4,]   4   9    11   19
 [5,]   5  10    15   20

Quero extrair a submatriz cujas linhas têm a coluna três = 11. Ou seja:

      one two three four
 [1,]   1   6    11   16
 [3,]   3   8    11   18
 [4,]   4   9    11   19

Eu quero fazer isso sem loop. Eu sou novo no R, então isso provavelmente é muito óbvio, mas a documentação geralmente é um pouco concisa.

peter2108
fonte
4
A idéia básica em todas as respostas é que, se você tiver um vetor / matriz lógica (TRUEs e FALSEs) do mesmo tamanho que algum índice, selecionará apenas os casos VERDADEIROS. Execute os códigos entre [ ]as respostas e você verá isso mais claramente.
Sacha Epskamp 22/03

Respostas:

160

Isso é mais fácil se você converter sua matriz em um quadro de dados usando as.data.frame (). Nesse caso, as respostas anteriores (usando subconjunto ou m $ três) funcionarão, caso contrário, não funcionarão.

Para executar a operação em uma matriz , você pode definir uma coluna pelo nome:

m[m[, "three"] == 11,]

Ou pelo número:

m[m[,3] == 11,]

Observe que, se apenas uma linha corresponder, o resultado será um vetor inteiro, não uma matriz.

neilfws
fonte
19
se você precisar manter a matriz, então façam[m[,3] == 11,,drop=FALSE]
Joris Meys 22/03
@neilfws Qual será a solução se eu quiser definir alguns valores para um intervalo de colunas. por exemplo df <- df[!which(df$ARID3A:df$YY1 == "U"),], aqui eu quero remover as linhas do meu df, onde uma gama de colunas (ARID3A: YY1) contém o valor U .
Novato
Como isso funciona se você não deseja especificar os nomes das colunas, mas deseja trabalhar em todas as colunas da matriz?
user5359531
Hey @neilfws, como você pode adicionar uma declaração && a esta? Preciso obter dois valores de colunas ao mesmo tempo?
depurando XD
28
m <- matrix(1:20, ncol = 4) 
colnames(m) <- letters[1:4]

O comando a seguir selecionará a primeira linha da matriz acima.

subset(m, m[,4] == 16)

E isso selecionará os três últimos.

subset(m, m[,4] > 17)

O resultado será uma matriz nos dois casos. Se você deseja usar nomes de coluna para selecionar colunas, é melhor convertê-lo em um dataframe com

mf <- data.frame(m)

Então você pode selecionar com

mf[ mf$a == 16, ]

Ou você pode usar o comando subconjunto.

John
fonte
21

Vou escolher uma abordagem simples usando o pacote dplyr.

Se o quadro de dados for dados.

library(dplyr)
result <- filter(data, three == 11)
mavez DABAS
fonte
11

Subconjunto é uma função muito lenta e, pessoalmente, acho inútil.

Eu suponho que você tem uma data.frame, matriz, matriz chamada Matcom A, B, Ccomo nomes de coluna; então tudo que você precisa fazer é:

  • No caso de uma condição em uma coluna, digamos a coluna A

    Mat[which(Mat[,'A'] == 10), ]

No caso de várias condições em uma coluna diferente, você pode criar uma variável dummy. Suponha que as condições são A = 10, B = 5e C > 2, em seguida, temos:

    aux = which(Mat[,'A'] == 10)
    aux = aux[which(Mat[aux,'B'] == 5)]
    aux = aux[which(Mat[aux,'C'] > 2)]
    Mat[aux, ]

Ao testar a vantagem da velocidade system.time, o whichmétodo é 10x mais rápido que o subsetmétodo.

Mohamad Elmasri
fonte
6

Se sua matriz for chamada m, basta usar:

R> m[m$three == 11, ]
juba
fonte
@juba Qual será a solução se eu quiser definir alguns valores para um intervalo de colunas. por exemplo df <- df[!which(df$ARID3A:df$YY1 == "U"),], aqui eu quero remover as linhas do meu df, onde uma gama de colunas (ARID3A: YY1) contém o valorU
Novato
0

Se o conjunto de dados é chamado de dados, todas as linhas que atendem a uma condição em que o valor da coluna 'pm2.5'> 300 pode ser recebido por:

dados [dados ['pm2.5']> 300,]

Anvita Shukla
fonte