user 31466
user 31466

Reputation: 699

Compare each element of a variable within each group

Consider the data frame in R:

set.seed(36)

y <- runif(10,0,200)
group <- sample(rep(1:2, each=5))
d <- data.frame(y, group)

I want to compare all y against all y within each group. The following codes do this correctly:

d_split <- split(d, d$group)
a <- with(d_split[[1]],outer(y, y, "<="))
b <- with(d_split[[2]],outer(y, y, "<="))

But while I am doing this inside a function, and the number of group varies (group will be an argument of that function), then I cannot proceed in this manner. How can I elegantly write the last three line codes to compare all y against all y within each group?

Upvotes: 2

Views: 104

Answers (2)

akrun
akrun

Reputation: 887991

Here is an option without splitting

library(data.table)
setDT(d)[, as.data.table(outer(y, y, "<=")), group]
#    group    V1    V2    V3    V4    V5
#1:     1  TRUE  TRUE FALSE FALSE FALSE
#2:     1 FALSE  TRUE FALSE FALSE FALSE
#3:     1  TRUE  TRUE  TRUE FALSE  TRUE
#4:     1  TRUE  TRUE  TRUE  TRUE  TRUE
#5:     1  TRUE  TRUE FALSE FALSE  TRUE
#6:     2  TRUE  TRUE FALSE  TRUE FALSE
#7:     2 FALSE  TRUE FALSE  TRUE FALSE
#8:     2  TRUE  TRUE  TRUE  TRUE  TRUE
#9:     2 FALSE FALSE FALSE  TRUE FALSE
#10:    2  TRUE  TRUE FALSE  TRUE  TRUE

Or in a 'long' format with CJ

setDT(d)[, CJ(y, y), group][, V1 <= V2, group]

Upvotes: 3

Ronak Shah
Ronak Shah

Reputation: 389355

To perform the same operation for multiple groups we can use lapply and perform the outer operation for every group.

lapply(split(d, d$group), function(x) outer(x[["y"]], x[["y"]], "<="))

#$`1`
#      [,1] [,2]  [,3]  [,4]  [,5]
#[1,]  TRUE TRUE FALSE FALSE FALSE
#[2,] FALSE TRUE FALSE FALSE FALSE
#[3,]  TRUE TRUE  TRUE FALSE  TRUE
#[4,]  TRUE TRUE  TRUE  TRUE  TRUE
#[5,]  TRUE TRUE FALSE FALSE  TRUE

#$`2`
#      [,1]  [,2]  [,3] [,4]  [,5]
#[1,]  TRUE  TRUE FALSE TRUE FALSE
#[2,] FALSE  TRUE FALSE TRUE FALSE
#[3,]  TRUE  TRUE  TRUE TRUE  TRUE
#[4,] FALSE FALSE FALSE TRUE FALSE
#[5,]  TRUE  TRUE FALSE TRUE  TRUE

Upvotes: 4

Related Questions