0

I am trying to extend the answer from Find string in data.frame and Find multiple strings in entire dataframe.

How can I use the results of coordinations to extract the corresponding elements of the data.frame? Here, the results mean the ones from which() with arr.ind = TRUE or sapply()

mat = as.data.frame(matrix(1:9, nrow = 3))
mat[1, 3] = "12:14"
mat[2, 1] = "18:48"
mat[2, 2] = "10:10"


# using the "which()" option
which(mat == "10:10", arr.ind = TRUE)

# the expected result is (may be in a vector type):
# > "18:48"

# using the "sapply()" option
sapply(colnames(mat), function(x) grep(":", mat[, x]))

# the expected result is (may be in a vector type):
# > "18:48", "10:10", "12:14"

# if I use grepl() rather than grep()
text = mat[sapply(colnames(mat), function(x) grepl(":", mat[, x])), ]

# I get an unexpected result as:
# > text
#         V1    V2   V3
# 2    18:48 10:10    8
# NA    <NA>  <NA> <NA>
# NA.1  <NA>  <NA> <NA>
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
hlee
  • 195
  • 2
  • 12

2 Answers2

5

You're so close for the last one; you just want to use matrix indexing by passing it the matrix altogether instead of just for the rows (ie, you have an extra comma).

> mat[sapply(colnames(mat), function(x) grepl(":", mat[, x]))]
[1] "18:48" "10:10" "12:14"

Compared to

> mat[sapply(colnames(mat), function(x) grepl(":", mat[, x])),]
        V1    V2   V3
2    18:48 10:10    8
NA    <NA>  <NA> <NA>
NA.1  <NA>  <NA> <NA>
Aaron left Stack Overflow
  • 36,704
  • 7
  • 77
  • 142
  • Thank you. You have the right answer for applying the result with `sapply()`. I didn't acknowledge the difference between indexing with matrix and indexing for the rows. – hlee Oct 08 '19 at 02:33
  • Thanks for the check, but this really is the long way round; see @RonakShah's answer for a simpler way. You can change your accepted answer if you agree. – Aaron left Stack Overflow Oct 08 '19 at 03:52
  • 1
    I agree with both answers. Nevertheless, I accepted yours because it is the first uploaded one. However, as you say so, I will change the accepted answer (yours is also a great one). – hlee Oct 08 '19 at 05:02
3

We can use grep with value = TRUE after converting mat to matrix

grep(":", as.matrix(mat), value = TRUE)
#[1] "18:48" "10:10" "12:14"
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • Thank you for your reply. However, your answer is somewhat far from what I want to know because I didn't include any example code and detailed explanation at first, sorry. I've just added them. – hlee Oct 08 '19 at 02:29
  • Thank you! This is also a great and simple answer for the result with `sapply()`. – hlee Oct 08 '19 at 02:45
  • You'll not need `sapply` in this case since I converted `mat` to matrix it will look for pattern `:` in the entire data and return the ones which match. – Ronak Shah Oct 08 '19 at 02:47
  • Yes, your answer can be regarded as the one for the result with `sapply()`, but doesn't require using the function. Good. – hlee Oct 08 '19 at 03:41