Pilih baris matriks yang memenuhi suatu kondisi

144

Dalam R dengan sebuah matriks:

     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

Saya ingin mengekstrak submatrix yang barisnya memiliki kolom tiga = 11. Yaitu:

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

Saya ingin melakukan ini tanpa perulangan. Saya baru mengenal R jadi ini mungkin sangat jelas tetapi dokumentasi seringkali agak singkat.

peter2108
sumber
4
Ide dasar dalam setiap jawaban adalah bahwa jika Anda memiliki vektor / matriks logis (TRUE dan FALSE) dengan panjang yang sama dengan beberapa indeks, Anda hanya akan memilih kasus yang BENAR. Jalankan kode antara [ ]jawaban dan Anda akan melihat ini lebih jelas.
Sacha Epskamp

Jawaban:

160

Ini lebih mudah dilakukan jika Anda mengonversi matriks ke bingkai data menggunakan as.data.frame (). Jika demikian, jawaban sebelumnya (menggunakan subset atau m $ tiga) akan berfungsi, jika tidak maka tidak akan.

Untuk melakukan operasi pada sebuah matriks , Anda dapat mendefinisikan kolom dengan nama:

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

Atau dengan nomor:

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

Perhatikan bahwa jika hanya satu baris yang cocok, hasilnya adalah vektor integer, bukan matriks.

neilfws
sumber
19
jika Anda perlu menyimpan matriks, maka lakukanm[m[,3] == 11,,drop=FALSE]
Joris Meys
@neilfws Apa yang akan menjadi solusi jika saya ingin mendefinisikan beberapa nilai untuk berbagai kolom. misalnya df <- df[!which(df$ARID3A:df$YY1 == "U"),], di sini saya ingin menghapus orang-orang baris dari df saya di mana berbagai kolom (ARID3A: YY1) berisi nilai U .
Pemula
Bagaimana cara kerjanya jika Anda tidak ingin menentukan nama kolom sama sekali tetapi ingin bekerja di semua kolom dalam matriks?
user5359531
Hai @neilfws, bagaimana Anda bisa menambahkan && pernyataan untuk yang ini? Saya perlu mendapatkan dua nilai kolom sekaligus?
debugging XD
28
m <- matrix(1:20, ncol = 4) 
colnames(m) <- letters[1:4]

Perintah berikut akan memilih baris pertama dari matriks di atas.

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

Dan ini akan memilih tiga yang terakhir.

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

Hasilnya akan menjadi matriks dalam kedua kasus. Jika Anda ingin menggunakan nama kolom untuk memilih kolom maka Anda sebaiknya mengonversinya menjadi dataframe

mf <- data.frame(m)

Maka Anda dapat memilih dengan

mf[ mf$a == 16, ]

Atau, Anda bisa menggunakan perintah subset.

John
sumber
21

Saya akan memilih pendekatan sederhana menggunakan paket dplyr.

Jika bingkai data adalah data.

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

Subset adalah fungsi yang sangat lambat, dan saya pribadi merasa itu tidak berguna.

Saya menganggap Anda memiliki data.frame, array, matriks disebut Matdengan A, B, Csebagai nama kolom; maka yang perlu Anda lakukan adalah:

  • Dalam kasus satu kondisi pada satu kolom, katakanlah kolom A

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

Dalam kasus beberapa kondisi pada kolom yang berbeda, Anda bisa membuat variabel dummy. Misalkan kondisi A = 10, B = 5dan C > 2, maka kita harus:

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

Dengan menguji keunggulan kecepatan system.time, whichmetode ini 10x lebih cepat dari subsetmetode.

Mohamad Elmasri
sumber
6

Jika matriks Anda dipanggil m, cukup gunakan:

R> m[m$three == 11, ]
juba
sumber
@juba Apa yang akan menjadi solusi jika saya ingin mendefinisikan beberapa nilai untuk berbagai kolom. misalnya df <- df[!which(df$ARID3A:df$YY1 == "U"),], di sini saya ingin menghapus baris-baris itu dari df saya di mana rentang kolom (ARID3A: YY1) berisi nilaiU
Newbie
0

Jika dataset disebut data, maka semua baris yang memenuhi suatu kondisi di mana nilai kolom 'pm2.5'> 300 dapat diterima oleh -

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

Anvita Shukla
sumber