Sélectionnez les lignes d'une matrice qui remplissent une condition


144

En R avec une matrice:

     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

Je veux extraire la sous-matrice dont les lignes ont la colonne trois = 11. C'est-à-dire:

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

Je veux faire cela sans boucler. Je suis nouveau sur R donc c'est probablement très évident, mais la documentation est souvent quelque peu laconique.


4
L'idée de base dans chaque réponse est que si vous avez un vecteur / matrice logique (VRAI et FAUX) de la même longueur que certains index, vous ne sélectionnerez que les cas qui sont VRAI. Exécutez les codes entre [ ]les réponses et vous verrez cela plus clairement.
Sacha Epskamp

Réponses:


160

C'est plus facile à faire si vous convertissez votre matrice en un bloc de données en utilisant as.data.frame (). Dans ce cas, les réponses précédentes (utilisant un sous-ensemble ou m $ trois) fonctionneront, sinon elles ne le seront pas.

Pour effectuer l'opération sur une matrice , vous pouvez définir une colonne par son nom:

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

Ou par numéro:

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

Notez que si une seule ligne correspond, le résultat est un vecteur entier, pas une matrice.


19
si vous avez besoin de conserver la matrice, alors faitesm[m[,3] == 11,,drop=FALSE]
Joris Meys

@neilfws Quelle sera la solution si je veux définir des valeurs pour une plage de colonnes. par exemple df <- df[!which(df$ARID3A:df$YY1 == "U"),], ici , je veux supprimer les lignes de mon df où une gamme de colonnes (ARID3A: YY1) contient la valeur U .
Débutant le

Comment cela fonctionne-t-il si vous ne souhaitez pas du tout spécifier les noms de colonne, mais que vous souhaitez travailler sur toutes les colonnes de la matrice?
user5359531

Hey @neilfws, comment pouvez-vous ajouter une déclaration && à celle-ci? J'ai besoin d'obtenir deux valeurs de colonnes en même temps?
débogage XD

28
m <- matrix(1:20, ncol = 4) 
colnames(m) <- letters[1:4]

La commande suivante sélectionnera la première ligne de la matrice ci-dessus.

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

Et cela sélectionnera les trois derniers.

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

Le résultat sera une matrice dans les deux cas. Si vous souhaitez utiliser des noms de colonnes pour sélectionner des colonnes, il vaut mieux la convertir en un dataframe avec

mf <- data.frame(m)

Ensuite, vous pouvez sélectionner avec

mf[ mf$a == 16, ]

Ou, vous pouvez utiliser la commande subset.


21

Je vais choisir une approche simple en utilisant le package dplyr.

Si le dataframe est data.

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

11

Le sous-ensemble est une fonction très lente, et personnellement je le trouve inutile.

Je suppose que vous avez un data.frame, tableau, appelée matrice Matavec A, B, Ccomme les noms de colonnes; alors tout ce que vous avez à faire est:

  • Dans le cas d'une condition sur une colonne, disons la colonne A

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

Dans le cas de plusieurs conditions sur une colonne différente, vous pouvez créer une variable factice. Supposons que les conditions soient A = 10, B = 5et C > 2, alors nous avons:

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

En testant l'avantage de vitesse avec system.time, la whichméthode est 10 fois plus rapide que la subsetméthode.


6

Si votre matrice est appelée m, utilisez simplement:

R> m[m$three == 11, ]

@juba Quelle sera la solution si je veux définir des valeurs pour une plage de colonnes. par exemple df <- df[!which(df$ARID3A:df$YY1 == "U"),], ici, je veux supprimer ces lignes de mon df où une plage de colonnes (ARID3A: YY1) contient la valeurU
Débutant

0

Si l'ensemble de données est appelé data, alors toutes les lignes remplissant une condition où la valeur de la colonne 'pm2.5'> 300 peuvent être reçues par -

données [données ['pm2.5']> 300,]

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.