-3

I am a beginner in R.

Is there a cleverer way of removing all rows which have a negative entry? I first thought of writing a for/repeat/while loop to do that but that is old thinking for languages not based on matrix operations.

Is there a cleverer way of removing all rows which have -20 as one of the entries?

user6439024
  • 79
  • 1
  • 1
  • 8
  • 1
    For an exact match of -20, you could use `m[rowSums(m == -20) == 0, ]` – talat Jun 08 '16 at 07:54
  • @docendodiscimus Although the question is probably a duplicate, I suggest that you post your comment as an answer. In my opinion this is the shortest and most efficient solution. – RHertel Jun 08 '16 at 09:45

2 Answers2

1

Rephrasing your condition to "keeping all rows where all entries are non negative" yields:

M[apply(M, 1, function(x) all(x >= 0)),] #This also removes rows with -20.

If you insist on using subset, you can use

subset(M, apply(M, 1, function(x) all(x >= 0)))

Edit: I interprete the comment by @user6439024 that his matrix is "22 2.663 330.2 1.9; 52 3.387 118.0 1.9; 78 3.498 187.3 1.85; 61 -0.221 298.4 1.8; 19 0.444 210.5 1.6;" as follows:

M <- matrix(c(22,  2.663, 330.2, 1.9, 
              52,  3.387, 118.0, 1.9, 
              78,  3.498, 187.3, 1.85, 
              61, -0.221, 298.4, 1.8, 
              19,  0.444, 210.5, 1.6), byrow = TRUE, ncol = 4)
Qaswed
  • 3,649
  • 7
  • 27
  • 47
  • Perhaps I have not written clearly enough. If matrix M is 22 2.663 330.2 1.9; 52 3.387 118.0 1.9; 78 3.498 187.3 1.85; 61 -0.221 298.4 1.8; 19 0.444 210.5 1.6; then I would like to remove the fourth row completely. – user6439024 Jun 08 '16 at 07:58
  • @Qaswed my code was similar to yours but I didn't have the all() function. – DarrenRhodes Jun 08 '16 at 08:05
  • @user6439024 in the matrix you posted is no "-20", only "-0.221" (at least for me, these are different things). If your question title is closer to what you want, than your question you want to exclude every row with a negative value, use `M[apply(M, 1, function(x) all(x >= 0)),]`. – Qaswed Jun 08 '16 at 08:25
  • Yes, thanks to both of you. I had two questions - one to remove rows with any entry negative and one to remove rows with -20 anywhere in the row. I understand your answers now. Is there an equally nice way to write with subset something like Mnew = subset(M, any(M[,] != -20)) ? – user6439024 Jun 08 '16 at 08:52
  • If you remove all rows with a negative value, you automatically also remove all rows with a value of -20... If you mean something else, be make your question more precise. – Qaswed Jun 08 '16 at 09:09
  • Those were two different questions. You have essentially answered both of them. Thanks. – user6439024 Jun 08 '16 at 09:31
  • "I first thought of writing a for/repeat/while loop..." The `*apply` functions are only wrappers to ordinary loops. More information [here](http://stackoverflow.com/a/2276001/4770166). – RHertel Jun 08 '16 at 09:40
1

Another option would be using Reduce with |

M[!Reduce(`|`, split(M < 0, col(M))),]

Or

M[Reduce(`&`, split(M >= 0, col(M))),]

data

M <- structure(c(22, 52, 78, 61, 19, 2.663, 3.387, 3.498, -0.221, 
0.444, 330.2, 118, 187.3, 298.4, 210.5, 1.9, 1.9, 1.85, 1.8, 
1.6), .Dim = c(5L, 4L))
akrun
  • 874,273
  • 37
  • 540
  • 662