3

Let us say I have a Rle like so, of length 10:

b = rle(c("H", "T", "T", "H", "H", "H", "H", "H", "T", "H"))

How can I get the length of this object without using inverse.rle?

length(inverse.rle(b))
# 10

I have some sparse Rles representing chromosomes and they can have a length of hundreds of millions so I would rather not use inverse.


akruns answer does not work on my data:

> a
$ mydata
numeric-Rle of length 57442693 with 12471 runs
  Lengths: 2709826     100   31062     100 ...       2     232     100      47
  Values :       0       1       0       1 ...       1       0       1       0

> a$lengths
NULL
The Unfun Cat
  • 29,987
  • 31
  • 114
  • 156

3 Answers3

6

As the rle is a list object with lengths and values as elements of the list, we can extract the lengths and sum

sum(b$lengths)
#[1] 10
akrun
  • 874,273
  • 37
  • 540
  • 662
2

Regarding your edit: akrun’s answer still generally works, you just need to adapt it slightly to your Rle data type:

I don’t know what function you’re using here but in case this is anything like the Bioconductor Rle S4 class, the solution would be

sum(s@lengths)

That is, instead of the nested name lengths you have to use the S4 slot name lengths. More generally, you can find out which solution works by inspecting:

  1. The object names via names(obj).
  2. Or, in the case of an S4 object, its slot names: slotNames(obj).
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
2

For the S4vectors class Rle you need to use the method runLength, it has no accessor $length.

In my example above, this becomes runLength(a[[1]]).

The Unfun Cat
  • 29,987
  • 31
  • 114
  • 156
  • For any other R noobs ending up here, `sum(runLength(a[[1]]))` works for me, but also `sum(a$peak1@lengths)` and `sum(a[1]$peak1@lengths)` work if you want to use the name (which in my case is `peak1`..`peakn`). I get the same exact result. Of course, your names must be unique. – hepcat72 Jun 01 '23 at 14:34