-5

I have two lists that contain S4 objects. Now I want to ask if an element of list_1 contains an element of list_2, like I do in the following example for lists of character vectors.

s<-list(a=LETTERS[1:3],b=LETTERS[4:6])
t<-list(n=LETTERS[1:3],v=LETTERS[1:4])
s %in% t

But does it prove if the objects are identical? If not, how to select the element of list_1 which exists in list_2 without using a loop?

John Paul
  • 12,196
  • 6
  • 55
  • 75
Klaus
  • 1,946
  • 3
  • 19
  • 34
  • I still voting, most of my question which get an answer I accept. – Klaus Sep 03 '13 at 11:50
  • 3
    I just gave 9 examples where that wasn't true (until you very recently *did finally* accept some of the answers). I don't really mind, but it makes you seem like someone who is only interested in taking from the community without giving back. Also your example is not really representative of the problem (or perhaps poorly explained IMHO). – Simon O'Hanlon Sep 03 '13 at 11:53
  • Can you give a more explicit example of what your desired input/output would look like? You can use `slotNames`, `slot`, `lapply`, `mapply` to iterate over slots in an S4 object ... – Ben Bolker Sep 03 '13 at 12:55
  • @BenBolker I dont want to iterate with lapply or any loop, I want to ask if `list1 %in% list2` like above. But you should suggest the lists contains S4 objects. So my question is if the statement `list1 %in% list2` compare the objects if I would do it via identical. – Klaus Sep 03 '13 at 12:58

3 Answers3

5

If you want to compare S4 objects I believe you will have to use (as Ben Bolker suggested) a mixture of functions slotNames, slot, and sapply.

setClass("MyClass",representation(Slot1="vector",Slot2="vector"))
x <- new("MyClass")
x@Slot1 <- 1:4
x@Slot2 <- LETTERS[1:4]
y <- new("MyClass")
y@Slot1 <- 1:4
y@Slot2 <- LETTERS[4:6]

id <- function(a,b){
        sapply(slotNames(a),function(x)identical(slot(a,x),slot(b,x)))
        }

id(x,y)
Slot1 Slot2 
 TRUE FALSE 

And now if you want to extend that to a list of S4 objects, use on top of that Metrics solution:

X <- new("MyClass")
X@Slot1 <- 1:5
X@Slot2 <- LETTERS[1:4]
Y <- new("MyClass")
Y@Slot1 <- 1:4
Y@Slot2 <- letters[1:4]

a <- list(l1 = x, l2 = X)
b <- list(l1 = y, l2 = Y)

Map(id, a, b)
$l1
Slot1 Slot2 
 TRUE FALSE 

$l2
Slot1 Slot2 
FALSE FALSE 
plannapus
  • 18,529
  • 4
  • 72
  • 94
  • I think you can also compare the whole object via identical so you can use `id <- function(a,b){ sapply(a,function(x) any(Map(identical,x,b))) }` – Klaus Sep 03 '13 at 14:58
2

You can use Map for that:

Map(function (x,y) x %in% y, s, t)
$a
[1] TRUE TRUE TRUE

$b
[1]  TRUE FALSE FALSE

Or, as suggested by @plannapus just use:

Map(`%in%`,s,t) 
Metrics
  • 15,172
  • 7
  • 54
  • 83
  • it's not clear to me that this is what the OP wants (although they haven't yet succeeded in making it very clear): I *think* they want the analogue of what they have shown above, but for S4 classes with slots rather than for lists with elements ... – Ben Bolker Sep 03 '13 at 13:51
  • @BenBolker, you are right. Till now I do it like I discribe and will see if it will crash, because of my doubts that `%in%` is not the same like `identical`. – Klaus Sep 03 '13 at 14:10
  • 1
    `%in%` checks if elements of x are included in elements of y, while `identical` checks if x and y are equals and of the same class. There are indeed not the same. You can use, by the way, a variation of @Metrics solution with function `identical`: `Map(identical,s,t)`. If you want to use `%in%` or `identical` over slots of your own S4 class you will have to define your own function I believe. – plannapus Sep 03 '13 at 14:17
  • @plannapus, you are right I have to use Map(identical,a,b) if want a the solution I suggest. Is there a way to define a operator like %in% which also works wihth lists of arbitrary objects. Because till now I do not realy understand why I could compare character vectors but no S4 objects. – Klaus Sep 03 '13 at 14:29
-2

Now I define a operator, did I do this in the right way?

"%inS4%" <- function(a,b) sapply(a,function(x) any(unlist(Map(identical,list(x),b))))
setClass(Class = "MyClass",
         representation = representation(name = "character",
                                         type = "character"
         )
)

a<-list(new("MyClass",name="abc",type="abc"),new("MyClass",name="abc",type="123"))
b<-list(new("MyClass",name="abc",type="123"),new("MyClass",name="abc",type="123"))

a %inS4% b
Klaus
  • 1,946
  • 3
  • 19
  • 34
  • @Metrics Yes and No, its similar, my solution is more general it compares and I can compare lists of objects like I do in start post with the lists of character vectors. – Klaus Sep 03 '13 at 20:40