Filter a list of data frames based on the first value in a column

Viewed 56

I have some data, example here:

 dat1 <- data.frame(a = c("5","10","15","20"), b = c("0.1","0.2","0.3","0.4"))
 dat2 <- data.frame(a = c("15","20","25","30"), b = c("0.5","0.6","0.7","0.8"))
 datalist <-list (dat1,dat2)

Giving me a format like this

    [[1]]
   a   b
1  5 0.1
2 10 0.2
3 15 0.3
4 20 0.4

   [[2]]
   a   b
1 15 0.5
2 20 0.6
3 25 0.7
4 30 0.8

I want to be able to filter the list of data frames with the condition that the first value of column a should be <= 10. So in this scenario the output would be just the first data frame [[1]], and the second data frame would be ignored entirely.

Desired output

    [[1]]
   a   b
1  5 0.1
2 10 0.2
3 15 0.3
4 20 0.4

Any advice would be greatly appreciated! Thanks

3 Answers

You can use sapply to get a vector of logicals indicating whether each element of a list meets a certain condition. This can then be applied to subset the list in the usual way with [. E.g:

datalist[sapply(datalist, function(x){as.numeric(x[[1,"a"]]) <= 10})]

will return only the first element in your example.

(Note the as.numeric is necessary because your numbers are stored as character strings here)

We can also use keep function from purrr. It takes a predicate function .p and apply it on every element of a list and return those elements that predicate function equals to a single TRUE.

lirbary(purrr)

datalist %>%
  keep(~ .x[["a"]][1] %>% as.numeric() <= 10)

[[1]]
   a   b
1  5 0.1
2 10 0.2
3 15 0.3
4 20 0.4

We may use Filter from base R

Filter(\(x) as.numeric(x$a[1]) <= 10, datalist)
[[1]]
   a   b
1  5 0.1
2 10 0.2
3 15 0.3
4 20 0.4
Related