I want to identify which row matches the information in a vector. As an example, I'll use the iris
dataset (in tibble
format to better approximate my situation): iris %>% as_tibble()
. Then I have a tibble with a single row, which came directly from the original dataset:
choice <– structure(list(Sepal.Length = 4.5, Sepal.Width = 2.3, Petal.Length = 1.3,
Petal.Width = 0.3, Species = structure(1L, .Label = c("setosa",
"versicolor", "virginica"), class = "factor")), row.names = c(NA,
-1L), class = c("tbl_df", "tbl", "data.frame"))
# A tibble: 1 x 5
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<dbl> <dbl> <dbl> <dbl> <fct>
1 4.5 2.3 1.3 0.3 setosa
I want to identify which row matches this exactly. I think it's better if it's a vector, but that's going to depend on what the function is; if that's the case, than you just have to add an as.numeric()
to that choice
.
The correct row is 42.
This Example illustrates how to use the is.element function to select specific data frame rows based on the values of a vector object. Within the is.element function, we have to specify the column of our data and the name of our vector:
Function for finding matching rows between two matrices or data.frames. First the matrices or data.frames are vectorized by row wise pasting together the elements. Then it uses the function match. Thus the function returns a vector with the row numbers of (first) matches of its first argument in its second.
Instead, you could use a formula using a combination of SUMPRODUCT, INDEX and ROW functions, such as this one: You use the SUMPRODUCT function to find out the row where both criteria are met, and return the corresponding row number using the ROW function.
Function for finding matching rows between two matrices or data.frames. First the matrices or data.frames are vectorized by row wise pasting together the elements. Then it uses the function match.
One option is Map
. With Map
, we compare (==
) the corresponding elements (here the unit is a column) of 'iris' and 'choice' (as choice have only a single row, that element is recycled), returning a list
of logical
vectors which is then Reduce
d to a single logical vector
with &
i.e. it checks for the elementwise corresponding elements of the list
(columns of iris converted to logical), returns TRUE if all the elements are TRUE), then wrap with which
to get the position index of that logical vector
which(Reduce(`&`, Map(`==`, iris, choice)))
#[1] 42
Or another option is to replicate the rows of 'choice' to make the dim same as 'iris', do a ==
, use rowSums
and check if it is equal to number of columns
library(tidyr)
which(rowSums(iris == uncount(choice, nrow(iris))) == ncol(iris))
#[1] 42
Or this can be done in tidyverse
. Create a row number column (row_number()
), use filter
with if_all
to loop across the column names except the 'rn', compare with the extracted corresponding column of 'choice', so that it returns the row only when all the columns for that row are TRUE (if_all
, if_any
- is either one of them), pull
the column 'rn' as a vector
library(dplyr)
iris %>%
mutate(rn = row_number()) %>%
filter(if_all(all_of(names(choice)),
~ . == choice[[cur_column()]])) %>%
pull(rn)
#[1] 42
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With