Reputation: 101
I have the following df
df <- data.frame(group=c("a","a","a","b","b","b","b","b","c","c","c","c"),
length=c(1.2,1.4,1.1,1.0,2.1,1.4,1.3,1.3,1.1,1.0,1.8,1.4),
weight = c(.3,.2,.3,.5,.7,.4,.3,.4,.7,.8,.4,.1))
i would like to be able to produce a logical vector of the same length based on the minimum "weight" value in each "group". For the above example the result should be
[1] FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE
I apologize if possibly the question is very simple, but i cant work my way around it.
Upvotes: 2
Views: 126
Reputation: 99361
You could write a short is.min
function (if you're into that sort of thing), and then use by
with is.min
.
This is somewhat similar to the answer given by @sgibb. Actually, since the edit of is.min
, it's almost exactly the same. But I'll leave it here in case you've never seen unlist
, with
, and/or by
.
> is.min <- function(x){ x == min(x) }
> unlist(with(df, by(weight, group, is.min)))
## a1 a2 a3 b1 b2 b3 b4 b5 c1 c2 c3 c4
## FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE
Upvotes: 1
Reputation: 25736
Try ave
(for details see ?ave
):
d <- ave(df$weight, df$group, FUN=function(x){min(x) == x})
d
# [1] 0 1 0 0 0 0 1 0 0 0 0 1
as.logical(d)
# [1] FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE
Upvotes: 1