Adam Amin
Adam Amin

Reputation: 1456

How to find a column value based on the unique value for another column

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

Answers (2)

tmfmnk
tmfmnk

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

BENY
BENY

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

Related Questions