Filter rows based on vector index instead of column name or index

Viewed 556

I have a very simple sample data frame df_test as:

df_test <- data.frame("A" = 1:5)    

I would like to select the row containing 5. I know I can achieve it by using the filter() command as:

df_analysis <- df_test %>% 
  filter(A == 5)    

However, I want to run a for loop (as the actual data set has many variables and is complex), thus instead of filtering columns manually one by one, I would like to run a for loop of columns that can pick one variable at a time and filter rows accordingly. For this example, I create a character vector v as v = c("A").

Now to filter, instead of using the column name, when I try to use this vector index as:

df_analysis <- df_test %>% 
  filter(v[1] == 5)    

It produces 0 rows instead of 1.

How can I filter rows using vector index instead of column index or name?

Thanks!

3 Answers

With the addition of purrr, you can do:

map(.x = v,
    ~ df_test %>%
     filter(across(all_of(.x)) == 5))

[[1]]
  A
1 5

We can use base R

df_test[df_test[[v]] == 5, , drop = FALSE]

Or with dplyr, by converting to symbol and evaluate (!!)

library(dplyr)
df_test %>%
     filter(!! rlang::sym(v) == 5)
#  A
#1 5

Or with .data

df_test %>%
      filter(.data[[v]] == 5)

In its current form, your filter operation compares the literal string "A" (i.e., the contents of v[1]) to the numeric 5, which is of course always false and therefore can't return any valid rows. Instead, you'd need to pass the variable A (contained in df_test) as the first argument to filter(). You can do this by using get() like so:

df_analysis <- df_test %>% 
  filter(get(v[1]) == 5)

The other solution here using purrr is honestly much better, but I wanted to point out why your code didn't work as expected.

Related