Online training class for Clinical R programming batch starts on Monday, 02Feb2026.
Click here for details.
library(tidyverse)
class<-tribble(
~Name,~Sex,~Age,~Height,~Weight,
"Alfred","M",14,69,112.5,
"Alice","F",13,56.5,84,
"Barbara","F",13,65.3,98,
"Carol","F",14,62.8,102.5,
"Henry","M",14,63.5,102.5,
"James","M",12,57.3,83,
"Jane","F",12,59.8,84.5,
"Janet","F",15,62.5,112.5,
"Jeffrey","M",13,62.5,84,
"John","M",12,59,99.5,
"Joyce","F",11,51.3,50.5,
"Judy","F",14,64.3,90,
"Louise","F",12,56.3,77,
"Mary","F",15,66.5,112,
"Philip","M",16,72,150,
"Robert","M",12,64.8,128,
"Ronald","M",15,67,133,
"Thomas","M",11,57.5,85,
"William","M",15,66.5,112,
)
only_one_in_group<-class %>%
group_by(age) %>%
mutate(nrows=n()) %>%
filter(nrows==1) class <- data.frame(
name = c("Alfred", "Alice", "Barbara", "Carol", "Henry", "James", "Jane", "Janet", "Jeffrey", "John", "Joyce", "Judy", "Louise", "Mary", "Philip", "Robert", "Ronald", "Thomas", "William"),
sex = c("M", "F", "F", "F", "M", "M", "F", "F", "M", "M", "F", "F", "F", "F", "M", "M", "M", "M", "M"),
age = c(14, 13, 13, 14, 14, 12, 12, 15, 13, 12, 11, 14, 12, 15, 16, 12, 15, 11, 15),
height = c(69, 56.5, 65.3, 62.8, 63.5, 57.3, 59.8, 62.5, 62.5, 59, 51.3, 64.3, 56.3, 66.5, 72, 64.8, 67, 57.5, 66.5),
weight = c(112.5, 84, 98, 102.5, 102.5, 83, 84.5, 112.5, 84, 99.5, 50.5, 90, 77, 112, 150, 128, 133, 85, 112)
, stringsAsFactors = FALSE
)
only_one_in_group_tmp <- class
only_one_in_group_tmp$nrows <- ave(
only_one_in_group_tmp$age,
only_one_in_group_tmp$age,
FUN = length
)
only_one_in_group_tmp <- only_one_in_group_tmp[only_one_in_group_tmp$nrows == 1, ]
only_one_in_group <- only_one_in_group_tmp We start by creating a temporary copy of the dataset so the original data remains unchanged.
ave(only_one_in_group_tmp$age, only_one_in_group_tmp$age, FUN = length)
The ave() function is used to perform a group-wise calculation and return the result back to each row.
Here, the first age represents the values being processed, and the second age defines the grouping variable.
Within each age group, length counts how many rows share that age value.
This count is then repeated for every row belonging to the same age group.
The resulting vector is assigned to a new column named nrows, which now holds the group size for each record.
only_one_in_group_tmp[nrows == 1, ]
Row subsetting is used to keep only those records where the age value appears exactly once in the dataset.
Finally, the filtered dataset is assigned to a new object, which contains only records that are unique within their age group.
Overall logic
Compute group size → attach it to each row → retain only groups with a single observation.