Reputation: 1456
I have the following dataset:
Class Value
A 5.4
A 5.4
A 5.4
B 3.6
B 2.7
C 4.02
C 4.02
C 4.02
D 6.33
D 6.33
What I want is to retrieve only the classes that have similar values, which in this case should return the class A
and D
but not, for example, the class B
since it has two different values.
To do that, I tried the following:
sub <- dataset[as.logical(ave(dataset$Value, dataset$Class, FUN = function(x) all(x==x))), ]
But this returns all the classes which I don't want.
Can someone help me with that?
Upvotes: 1
Views: 53
Reputation: 39858
With tidyverse
you can do:
df %>%
group_by(Class) %>%
filter(all(Value == first(Value)))
Or:
df %>%
group_by(Class) %>%
filter(n_distinct(Value) == 1)
Or:
df %>%
group_by(Class) %>%
filter(all(Value %/% first(Value) != 0))
Or:
df %>%
group_by(Class, Value) %>%
mutate(temp = seq_along(Value)) %>%
group_by(Class) %>%
filter(sum(temp[temp == 1]) == 1) %>%
select(-temp)
Or basically the same as the post from @W-B:
df %>%
group_by(Class) %>%
filter(length(unique(Value)) == 1)
Upvotes: 0
Reputation: 323226
Using aggregate
with number of unique
(length(unique)
)
filterdf=aggregate(Value ~ Class, df, function(x) length(unique(x)))
df[df$Class%in%filterdf[filterdf$Value==1,]$Class,]
Class Value
1 A 5.40
2 A 5.40
3 A 5.40
6 C 4.02
7 C 4.02
8 C 4.02
9 D 6.33
10 D 6.33
Alternative from markus
idx <- with(df, ave(Value, Class, FUN = function(x) length(unique(x))) == 1)
df[idx, ]
Upvotes: 3