Reputation: 14454
Let's say I have these two vectors:
x <- c(1,2,4,6,7)
y <- c(3,7)
How can I split x
into the elements that are smaller than each element of y
? For example: c(1,2) | c(4,6,7)
.
.
I guess one option would be to do a double loop and return the smallest element in y
that is smaller than the current one in x
: c(3,3,3,7,7)
. I could then split using this vector.
j <- 1
sapply(x, function(i){
if (i <= y[j]) {
y[j]
} else {
if (j < length(y)){
j <- j + 1
}
y[j]
}
})
I feel like there's a cleverer way to do this, but I can't figure it out.
Upvotes: 2
Views: 1569
Reputation: 12935
Using cut
and split
in base R:
lapply(y, function(a) split(x, cut(x, c(-Inf, a, Inf))))
# [[1]]
# [[1]]$`(-Inf,3]`
# [1] 1 2
# [[1]]$`(3, Inf]`
# [1] 4 6 7
# [[2]]
# [[2]]$`(-Inf,7]`
# [1] 1 2 4 6 7
# [[2]]$`(7, Inf]`
# numeric(0)
Upvotes: 2
Reputation: 353
maybe not the best solution but it is quicker:
z <- x < min(y)
end <- x[z]
Upvotes: 0
Reputation: 150
Here is how I would do it:
x <- c(1,2,4,6,7)
y <- c(3,7)
out <- list(x[x < min(y)], x[!x < min(y)])
Here is the result:
> out
[[1]]
[1] 1 2
[[2]]
[1] 4 6 7
Upvotes: 4
Reputation: 38520
Here is a base R method using split
and findInterval
:
split(x, findInterval(x, y, rightmost.closed=TRUE))
$`0`
[1] 1 2
$`1`
[1] 4 6 7
The findInterval
function returns a vector that categorizes the variable values in x along your criteria in y. The split
function separates the vector as desired and returns a named list.
Upvotes: 4