How can I coerce "list" to S4 "List" (reproducible example is available)?
1
0
Entering edit mode
@jurat-shahidin-9488
Last seen 4.7 years ago
Chicago, IL, USA

Hi everyone:

Is there any way to coerce simple list-like object "list" to S4 "List" object? Apparently, I used nested-lapply on my functions, and I checked its return type as "list". I want "List" like objects instead. Is that possible to do such coercion in R? if answer is yes, how can I do that ? Thanks

Here is the reproducible example to understand the problem that I stated :

foo <- GRanges(
  seqnames=Rle(c("chr1", "chr2", "chr3", "chr4"), c(3, 2, 1, 2)),
  ranges=IRanges(seq(1, by=9, len=8), seq(7, by=9, len=8)),
  rangeName=letters[seq(1:8)], score=sample(1:20, 8, replace = FALSE))

bar <- GRanges(
  seqnames=Rle(c("chr1", "chr2", "chr3","chr4"), c(4, 3, 1, 1)),
  ranges=IRanges(seq(2, by=5, len=9), seq(4, by=5, len=9)),
  rangeName=letters[seq(1:9)], score=sample(1:20, 9, replace = FALSE))

moo <- GRanges(
  seqnames=Rle(c("chr1", "chr2", "chr3","chr4"), c(3, 4, 2,1)),
  ranges=IRanges(seq(5, by=7, len=10), seq(8, by=7, len=10)),
  rangeName=letters[seq(1:10)], score=sample(1:20, 10, replace = FALSE))

# hitIndex;

grl <- GRangesList(bar, moo)
res <- lapply(grl, function(ele_) {
    tmp <- as(findOverlaps(foo, ele_), "List")
  })

obj.ov <- lapply(res, function(ele_) {
  re <- lapply(grl, function(obj) {
    id0 <- as(which.max(extractList(obj$score, ele_)), "List")
    id0 <- id0[!is.na(id0)]
  })
  re <- re[!duplicated(re)]
})

I want to coerce obj.ov to S4 "List"  ?. Any way to do this in R? Any possible approach, ideas, are appreciated. 

Best regards;

Jurat

coercion data manipulation s4vectors List • 2.0k views
ADD COMMENT
0
Entering edit mode

Same question on Biostars: https://www.biostars.org/p/200238/

ADD REPLY
2
Entering edit mode
@gordon-smyth
Last seen 7 minutes ago
WEHI, Melbourne, Australia

Reading help("List-class") reveals

​as(res, "List")
ADD COMMENT
0
Entering edit mode

Dear Gordon:

I tried this way, but it won't work, as.obj.ov can't be expandable as obj.ov like hit-index vector,plus it gave me this :

as.obj.ov <- as(obj.ov, "List")

> as(obj.ov, "List")
List of length 2

Here is further explanation that substantiate my attempt:

bar.ovHit <- res[[1]]
bar.ov_keepOne <- as(which.max(extractList(bar$score, bar.ovHit)), "List")
bar.ov.idx <- bar.ov_keepOne[!is.na(bar.ov_keepOne)]
bar.ov <- unlist(extractList(seq_along(bar), bar.ovHit)[bar.ov.idx])
bar[bar.ov]

Actually, I have to add my possible next step after I got res, now I inserted that part as well, please re run the scripts. I am expecting obj.ov as S4 "List", and obj.ov must be expandable as it was. Any possible solution for this kind of coercion. Thank you

 

ADD REPLY
1
Entering edit mode

Hi Jurat,

Gordon is right. as(res, "List") is the way to coerce an ordinary list to List. It works as expected. Note that res is a nested list structure (the list elements in it are IntegerList objects). Maybe by coercing res to List you were expecting to get something like an IntegerListList object? There is no such class in Bioconductor. This is why you get a generic List object instead. Technically it's a SimpleList object. If you look at its internal representation, it's just a wrapper around an ordinary list. Therefore you won't get any benefits in terms of performance by using this SimpleList object vs using an ordinary list.

As a general advice: it's hard to compute efficiently on nested list structures so it's better if you can avoid them. That often requires taking a completely different approach to how you implement things. This can be hard too. We can help but we need to know a little bit more about what you're trying to achieve.

BTW, the last part of the code in your original post gives me an error:

> obj.ov <- lapply(res, function(ele_) {
+   re <- lapply(grl, function(obj) {
+     id0 <- as(which.max(extractList(obj$score, ele_)), "List")
+     id0 <- id0[!is.na(id0)]
+   })
+   re <- re[!duplicated(re)]
+ })
Error: subscript contains out-of-bounds indices

Cheers,

H.

ADD REPLY
0
Entering edit mode

Dear Herve:

Thank you for your comprehensive explanation for this issue. Yes, using nestled lapply is not good idea, I just proved this and got my solution finally. Therefore, in my solution, there is no need to use nested lapply, no need of using such coercion, I was wrong about the concepts. once again thanks for you are giving me underlying principle behind coercion in Bioconductor. 

regarding the error, please try this modification :

obj.ov <- lapply(grl, function(ele_) {
  res <- as(findOverlaps(foo, ele_), "List")
  idx <- as(which.min(extractList(ele_$score, res)), "List")
  idx <- idx[!is.na(idx)]
  res[idx]
})

If you are able give any suggestion to optimize above code to make more compatible and efficient, I will be grateful for your effort. Thank you

Jurat

ADD REPLY

Login before adding your answer.

Traffic: 422 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6