I have a dataframe like this
ID <- c(\"A\",\"A\",\"A\",\"B\",\"B\",\"C\",\"C\")
Measurement <- c (\"Length\",\"Breadth\",\"Breadth\",\"Breadth\",\"Leng
Base R: Give a logical value created by ave
to the i
parameter of "["
:
df[ ave( as.character(df$Measurement), df$ID, FUN=function(x) length(unique(x)) ) > 1, ]
ID Measurement Value
1 A Length 4.5
2 A Breadth 6.6
3 A Breadth 7.5
4 B Breadth 3.3
5 B Length 5.6
This is a case where I think the base solution is "dominated" in terms of easy of programming and intelligibility by both the data.table and the dplyr solutions offered. That is not often the case in my experience.
In dplyr, it would be
library(dplyr)
df %>% group_by(ID) %>% filter(n_distinct(Measurement) > 1)
## ID Measurement Value
## <fctr> <fctr> <dbl>
## 1 A Length 4.5
## 2 A Breadth 6.6
## 3 A Breadth 7.5
## 4 B Breadth 3.3
## 5 B Length 5.6
Using data.table
:
library(data.table)
DT <- data.table(df)
DT[, Count := length(unique(Measurement)), ID][Count > 1]
Edit
Alternatively, a much better one-liner suggested by @DavidArenburg:
setDT(df)[, if(uniqueN(Measurement) > 1) .SD, by = ID]
Another option is using anyDuplicated
df[with(df, ave(as.character(Measurement), ID, FUN = anyDuplicated)!=0),]