86

Given a data frame "foo", how can I select only those rows from "foo" where e.g. foo$location = "there"?

foo = data.frame(location = c("here", "there", "here", "there", "where"), x = 1:5, y = 6:10)
foo
#   location x  y
# 1     here 1  6
# 2    there 2  7
# 3     here 3  8
# 4    there 4  9
# 5    where 5 10

Desired result, "bar":

#   location x y
# 2    there 2 7
# 4    there 4 9
Henrik
  • 65,555
  • 14
  • 143
  • 159
wishihadabettername
  • 14,231
  • 21
  • 68
  • 85

3 Answers3

140

Here are the two main approaches. I prefer this one for its readability:

bar <- subset(foo, location == "there")

Note that you can string together many conditionals with & and | to create complex subsets.

The second is the indexing approach. You can index rows in R with either numeric, or boolean slices. foo$location == "there" returns a vector of T and F values that is the same length as the rows of foo. You can do this to return only rows where the condition returns true.

foo[foo$location == "there", ]
JoFrhwld
  • 8,867
  • 4
  • 37
  • 32
  • 2
    .@JoFrhwld - Isn't `subset()` not preferred method? Detailed discussion [here](https://stackoverflow.com/questions/9860090/why-is-better-than-subset) – Chetan Arvind Patil Aug 09 '17 at 16:56
  • Is there a simple way of accessing both subset and foo minus the subset? I want to split my data into bar and (foo-bar). Obviously, I could repeat the above with !=, but is there a one-liner way? – schoon Sep 15 '17 at 06:37
  • Hello I am learning indexing and I have a question. Given that a specific set of columns can be extracted here, for example, `foo[foo$location == '"there",5:8]` what would happen if i try to assign a value to these like this: `foo[foo$location == "there",5:8] <-FALSE` – Sumedha Nagpal Dec 02 '19 at 21:51
  • very well explained.! – A1aks Jun 10 '20 at 16:12
5

Just to extend the answer above you can also index your columns rather than specifying the column names which can also be useful depending on what you're doing. Given that your location is the first field it would look like this:

    bar <- foo[foo[ ,1] == "there", ]

This is useful because you can perform operations on your column value, like looping over specific columns (and you can do the same by indexing row numbers too).

This is also useful if you need to perform some operation on more than one column because you can then specify a range of columns:

    foo[foo[ ,c(1:N)], ]

Or specific columns, as you would expect.

    foo[foo[ ,c(1,5,9)], ]
DryLabRebel
  • 8,923
  • 3
  • 18
  • 24
1

Another option could be using the function filter from dplyr. Here is a reproducible example:

foo = data.frame(location = c("here", "there", "here", "there", "where"), x = 1:5, y = 6:10)
library(dplyr)
filter(foo, location == "there")
#>   location x y
#> 1    there 2 7
#> 2    there 4 9

Created on 2022-09-11 with reprex v2.0.2

Quinten
  • 35,235
  • 5
  • 20
  • 53