1

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?

2 Answers 2

3

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, ]
Sign up to request clarification or add additional context in comments.

3 Comments

I was about to post a similar solution using ave which you might want to add as alternative. idx <- with(df, ave(Value, Class, FUN = function(x) length(unique(x))) == 1); df[idx, ]
@markus that is great thank you :-) , if you would like convert it as an answer I will definitively upvote for you man
That is kind of you. I found it too similiar to what you posted 1 minute earlier. Feel free to use it.
0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.