Вот базовое решение R
dfout <- df[order(factor(df$StudName, levels = unique(df$StudName)),
factor(df$Code, levels = c("V","P"))),]
такое, что
> dfout
StudName Code ID
3 John V a3
8 John V a8
1 John P a1
2 Sam V a2
5 Sam P a5
6 Alex V a6
4 Alex P a4
7 Stuart P a7
или
dfout <- do.call(rbind,
c(make.row.names = F,
lapply(split(df,factor(df$StudName, levels = unique(df$StudName))),
function(x) x[order(x$Code,decreasing = TRUE),])))
такое, что
> dfout
StudName Code ID
1 John V a3
2 John V a8
3 John P a1
4 Sam V a2
5 Sam P a5
6 Alex V a6
7 Alex P a4
8 Stuart P a7
ДАННЫЕ
df <- structure(list(StudName = c("John", "Sam", "John", "Alex", "Sam",
"Alex", "Stuart", "John"), Code = c("P", "V", "V", "P", "P",
"V", "P", "V"), ID = c("a1", "a2", "a3", "a4", "a5", "a6", "a7",
"a8")), class = "data.frame", row.names = c(NA, -8L))