Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

R output row and column index of dataframe with target values in a vector

Here I have a dataframe df:

structure(list(col1 = c("f", "h", "k", "p", "d", "n", "o", "i", 
"s", "a"), col2 = c("e", "d", "m", "g", "r", "h", "k", "p", "t", 
"i"), col3 = c("s", "e", "l", "c", "t", "f", "a", "p", "k", "d"
)), class = "data.frame", row.names = c(NA, -10L))
col1 col2 col3
f e s
h d e
k m l
p g c
d r t
n h f
o k a
i p p
s t k
a i d

And a vector vec containing the values that I would like to search in df:

vec <- c("a", "h", "ah")

I would like to output the column and row index of the element in the vector, with the first column being the element, the second column being the row index and the third column being the column index, like the following (the order of rows are not important), also, it should also take care of values not present in df:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

name row col
h    2   1
h    6   2
a    7   3
a    10  1
ah   NA  NA

I tried doing it with which or arrayInd, but it misses the final record of "a" (note the final row in the first column in df), also it throws an error at values (e.g. "ah") not present in df.

arrayInd(which(df == vec), dim(df), useNames = T)

which(df == vec, arr.ind = T)

     row col
[1,]   2   1
[2,]   6   2
[3,]   7   3

Also, I need to effectively add a column of "a" or "h" to the output. Note that I do not know the number of elements in vec, it can be 2 or 10 or more, I also don’t know how many columns are in df, but their column names have the pattern col{n}.

Any ideas will be appreciated, thanks!

>Solution :

Here’s a base R solution.

You can use arr.ind inside which. You would need to do this for each element in vec, so need to wrap it in an lapply and rbind the results:

do.call(rbind, lapply(vec, function(x) {
  y <- which(df == x, arr.ind = TRUE)
  if(length(y) == 0) y <- cbind(row = NA, col = NA)
  data.frame(name = x, y)}))
#>   name row col
#> 1    a  10   1
#> 2    a   7   3
#> 3    h   2   1
#> 4    h   6   2
#> 5    z  NA  NA
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading