3

From ?"[" in the details section:

Subsetting (except by an empty index) will drop all attributes except names, dim and dimnames.

Example:

myobj <- structure(list(a = c(1, 2, 3), b = c(4, 5, 6)), class = "myclass")
attr(myobj, "someattr") <- "Hello World"
myobj
# $a
# [1] 1 2 3

# $b
# [1] 4 5 6

# attr(,"class")
# [1] "myclass"
# attr(,"someattr")
# [1] "Hello World"

So if I subset the first position the attributes and classes are dropped:

myobj[-c(2)]
# $a
# [1] 1 2 3

The solution is to create a method, see here and here.

The solution is quite old though and I was wondering are there simpler/quicker ways to do this now so you dont have to create a method? rrapply comes to mind but I think it only works to recursively apply a function f to a set of elements of a list:

library(rrapply)
rrapply(myobj,  f = head, n = 1, how = "list")
# $a
# [1] 1

# $b
# [1] 4

# attr(,"class")
# [1] "myclass"
# attr(,"someattr")
# [1] "Hello World"

Is there a way to use rrapply to subset in the way I want to preserve the attributes and class or is there a simpler way to do this?

Thanks

user63230
  • 4,095
  • 21
  • 43

1 Answers1

4

1) gv Try get_vars (can be shortened to gv) in the collapse package:

library(collapse)
gv(myobj, -2)

giving:

$a
[1] 1 2 3

attr(,"class")
[1] "myclass"
attr(,"someattr")
[1] "Hello World"

2) Base R or NULL out the components you don't want:

replace(myobj, 2, NULL)

giving:

$a
[1] 1 2 3

attr(,"class")
[1] "myclass"
attr(,"someattr")
[1] "Hello World"

3) rrapply We can use rrapply with how = "prune" . The condition ensures that only components at the first level with the indicated names are returned.

library(rrapply)
cond <- function(x, .xname, .xpos) .xname %in% names(myobj)[-2] && .xpos == 1
rrapply(myobj, condition = cond, how="prune")

giving:

$a
[1] 1 2 3

attr(,"class")
[1] "myclass"
attr(,"someattr")
[1] "Hello World"
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341