Wybierz wiersze macierzy, które spełniają warunek

144

W R z macierzą:

     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

Chcę wyodrębnić podmacierz, której wiersze mają kolumnę trzecią = 11. To jest:

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

Chcę to zrobić bez zapętlania. Jestem nowy w R, więc jest to prawdopodobnie bardzo oczywiste, ale dokumentacja jest często nieco zwięzła.

peter2108
źródło
4
Podstawową ideą każdej odpowiedzi jest to, że jeśli masz logiczny wektor / macierz (PRAWDA i FAŁSZ) o tej samej długości co jakiś indeks, wybierzesz tylko te przypadki, które są PRAWDA. Uruchom kody [ ]w odpowiedziach, a zobaczysz to wyraźniej.
Sacha Epskamp

Odpowiedzi:

160

Jest to łatwiejsze do zrobienia, jeśli przekonwertujesz macierz na ramkę danych za pomocą metody as.data.frame (). W takim przypadku poprzednie odpowiedzi (używając podzbioru lub m $ trzy) będą działać, w przeciwnym razie nie.

Aby wykonać operację na macierzy , możesz zdefiniować kolumnę według nazwy:

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

Lub według numeru:

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

Zauważ, że jeśli pasuje tylko jeden wiersz, wynikiem jest wektor całkowity, a nie macierz.

neilfws
źródło
19
jeśli chcesz zachować matrycę, zrób tom[m[,3] == 11,,drop=FALSE]
Joris Meys
@neilfws Jakie będzie rozwiązanie, jeśli chcę zdefiniować pewne wartości dla zakresu kolumn. na przykładdf <- df[!which(df$ARID3A:df$YY1 == "U"),] , tutaj chcę usunąć te wiersze z mojego df gdzie szereg kolumn (ARID3A: YY1) zawiera wartość U .
Nowicjusz
Jak to działa, jeśli nie chcesz w ogóle określać nazw kolumn, ale chcesz pracować nad wszystkimi kolumnami w macierzy?
user5359531
Hej @neilfws, jak możesz dodać oświadczenie && do tego? Muszę uzyskać dwie wartości kolumn w tym samym czasie?
debugowanie XD
28
m <- matrix(1:20, ncol = 4) 
colnames(m) <- letters[1:4]

Następujące polecenie wybierze pierwszy wiersz powyższej macierzy.

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

A to spowoduje wybranie trzech ostatnich.

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

Wynik będzie macierzą w obu przypadkach. Jeśli chcesz używać nazw kolumn do wybierania kolumn, najlepiej byłoby przekonwertować je na ramkę danych z

mf <- data.frame(m)

Następnie możesz wybrać za pomocą

mf[ mf$a == 16, ]

Lub możesz użyć polecenia podzestaw.

Jan
źródło
21

Wybiorę proste podejście z wykorzystaniem pakietu dplyr.

Jeśli ramka danych to data.

library(dplyr)
result <- filter(data, three == 11)
mavez DABAS
źródło
11

Podzbiór to bardzo powolna funkcja i osobiście uważam ją za bezużyteczną.

Zakładam, że masz data.frame, tablicę, zwaną matrycę Matz A, B, Cjako nazwy kolumn; wtedy wszystko, co musisz zrobić, to:

  • W przypadku jednego warunku w jednej kolumnie, powiedzmy kolumnę A

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

W przypadku wielu warunków w różnych kolumnach można utworzyć zmienną zastępczą. Załóżmy, że warunki są A = 10, B = 5i C > 2to mamy:

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

Testując przewagę szybkości za pomocą system.time, whichmetoda jest 10x szybsza niż subsetmetoda.

Mohamad Elmasri
źródło
6

Jeśli twoja macierz jest wywołana m, po prostu użyj:

R> m[m$three == 11, ]
juba
źródło
@juba Jakie będzie rozwiązanie, jeśli chcę zdefiniować jakieś wartości dla zakresu kolumn. na przykład df <- df[!which(df$ARID3A:df$YY1 == "U"),]tutaj chcę usunąć te wiersze z mojego df, w których zakres kolumn (ARID3A: YY1) zawiera wartośćU
Newbie
0

Jeśli zbiór danych nazywa się danymi, wszystkie wiersze spełniające warunek, w którym wartość kolumny „pm2,5”> 300, mogą zostać odebrane przez -

data [data ['pm2,5']> 300,]

Anvita Shukla
źródło