Is there an R function for finding the rows that contains a specific element in a matrix?
Asked Answered
T

3

6

Let's say I have a 4x2 matrix.

x<- matrix(seq(1:8), 4)

That contains the following elements

1 5
2 6
3 7
4 8

For this specific example, let's say I want to remove the rows that contain a '2' or an '7' (without having to manually look in the matrix and remove them). How would I do this?

Here's something I came up with but it isn't doing what I want it to. I want it to return the row indices in the matrix that contain either a 2 or a 7.

remove<- which(2 || 7 %in% x)
x<- x[-remove,]

Can anyone help me figure this out?

Tibbitts answered 10/11, 2012 at 20:15 Comment(2)
which() is the correct function, but you need to read a bit more about the indexing syntax.Joan
x[-which(...), ] is dangerous in the event that which returns no match. Prefer x[!(...), ].Fatso
A
8
x[-which(x == 2 | x == 7, arr.ind = TRUE)[,1],] 

is the simplest, most efficient way I can think of.

the single '|' checks if each element is 2 or 7 (which '||' won't do). arr.ind gives each position as a pair of coordinates, rather than the default single number. [,1] selects each row which has a 2 or 7.

Hope that helps :)

Antisocial answered 10/11, 2012 at 20:37 Comment(2)
thanks @RyanGrannell. BTW, you have good R skills at just 19 years old. where did you learn how to program in R?Tibbitts
thanks, really glad my answer was helpful. To answer your question, I learned it in my spare time, using the R documentation, Twitter and of course Stack Exchange :)Zel
O
3

As @Dirk said, which is the right function, here is my answer:

index <- apply(x, 1, function(a) 2 %in% a || 7 %in% a)
> index
[1] FALSE  TRUE  TRUE FALSE
x[index, ]
Overdrive answered 10/11, 2012 at 20:24 Comment(2)
doesn't he want ``x[-index,]Sneed
Initially he wanted to remove them, then he came up to want it to return the row indices in the matrix that contain either a 2 or a 7..Overdrive
F
3

x[-which(...), ] is not the right approach... Why? See what happens in case which finds no match:

x <- matrix(8, nrow = 4, ncol = 2)
x[-which(x == 2 | x == 7, arr.ind = TRUE)[,1],] 
#      [,1] [,2]

(it returns nothing, while it should return the whole x.)

Instead, indexing with logicals is the safer approach: you can negate the vector of matches without risking the odd behavior shown above. Here is an example:

x[!(rowSums(x == 2 | x == 7) > 0), , drop = FALSE]

which can also be written in the shorter form:

x[!rowSums(x == 2 | x == 7), , drop = FALSE]
Fatso answered 10/11, 2012 at 22:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.