Home > other >  Get an element from a vector with its attribute in R
Get an element from a vector with its attribute in R

Time:11-21

gregexpr returns a list containing a vector with some additional data:

[[1]]
[1]  21 136 409 512 587 693
attr(,"match.length")
[1] 3 4 5 5 4 9

How do I extract just one element with a corresponding attribute at once?

[[1]]
[1] 409
attr(,"match.length")
[1] 5

CodePudding user response:

We may do

out <- lapply(lst1, `[`, 3)
attr(out, "match.length") <- attr(lst1, "match.length")[3]

-output

> out
[[1]]
[1] 409

attr(,"match.length")
[1] 5

data

lst1 <- structure(list(c(21, 136, 409, 512, 587, 693)),
 match.length = c(3, 
4, 5, 5, 4, 9))

CodePudding user response:

In general, there's no way for R to know that elements of the vector correspond 1-1 with elements of one of its attributes.

If you know this is true (as it is with gregexpr results), then the way to tell R about it is to set a class on the object, and write your own subsetting code. For example,

`[.gregexpr_result` <- function(x, i) {
  attrs <- lapply(x, function(element) {
    allattrs <- attributes(element)
    allattrs[["match.length"]] <- allattrs[["match.length"]][i]
    allattrs
  })
  x <- lapply(x, `[`, i)
  for (j in seq_along(x))
    attributes(x[[j]]) <- attrs[[j]]
  x
}

x <- paste(letters[1:2], letters[1:2])
result <- gregexpr("b", x)
class(result) <- "gregexpr_result"
result
#> [[1]]
#> [1] -1
#> attr(,"match.length")
#> [1] -1
#> attr(,"index.type")
#> [1] "chars"
#> attr(,"useBytes")
#> [1] TRUE
#> 
#> [[2]]
#> [1] 1 3
#> attr(,"match.length")
#> [1] 1 1
#> attr(,"index.type")
#> [1] "chars"
#> attr(,"useBytes")
#> [1] TRUE
#> 
#> attr(,"class")
#> [1] "gregexpr_result"
result[2]
#> [[1]]
#> [1] NA
#> attr(,"match.length")
#> [1] NA
#> attr(,"index.type")
#> [1] "chars"
#> attr(,"useBytes")
#> [1] TRUE
#> 
#> [[2]]
#> [1] 3
#> attr(,"match.length")
#> [1] 1
#> attr(,"index.type")
#> [1] "chars"
#> attr(,"useBytes")
#> [1] TRUE

Created on 2022-11-20 with reprex v2.0.2

  •  Tags:  
  • r
  • Related