Ответ 1
Еще один способ приблизиться к этому - поставить свои уровни факторов в их естественном порядке, в этом случае Freshman, Sophomore, Junior, Senior, а затем выбрать максимальное значение для каждого идентификатора, используя функцию which.max
для индексирования. Если вы сделаете это так, вам не придется беспокоиться о том, упорядочены ли ваши столбцы от самого низкого до высшего уровня для каждого идентификатора (как и при использовании функции last
).
library(dplyr)
df <-data.frame(ID=c(1,1,1,1,2,2,2,3,3),
current.grade=as.factor(c("Senior","Senior","Senior","Senior",
"Junior","Junior","Junior",
"Sophomore","Sophomore")),
grade.history=as.factor(c("Freshman","Sophomore","Junior","Senior",
"Freshman","Sophomore","Junior",
"Freshman","Sophomore")))
# Ordered vector of grades
gradeLookup = c("Freshman", "Sophomore", "Junior", "Senior")
# Reset the values in the grade columns to the ordering in gradeLookup
df[,-1] = lapply(df[,-1], function(x) {
factor(x, levels=gradeLookup)
})
# For each ID, select the values of current.grade and grade.history at the maximum
# value of grade.history
df %>% group_by(ID) %>%
summarise(current.grade.last = current.grade[which.max(grade.history)],
grade.history.last = grade.history[which.max(grade.history)])
ID current.grade.last grade.history.last
1 1 Senior Senior
2 2 Junior Junior
3 3 Sophomore Sophomore
ОБНОВЛЕНИЕ 2:. Поскольку вы хотите сортировать и фиксировать последнее значение (а не максимальное значение) по столбцу, а не целые строки, попробуйте следующее:
df %>% group_by(ID) %>%
summarise(current.grade.last = current.grade[length(grade.history)],
grade.history.last = grade.history[length(grade.history)])
END UPDATE 2
Имеются ли в ваших данных переменная времени, например год, срок или учебный год? Если это так, вы можете отказаться от current.grade
и direclty выбрать значение grade.history
в последний год посещаемости. Это даст вам каждый студент последнего уровня. Например (если ваша временная переменная называется year
):
df %>% group_by(ID) %>%
summarise(last.grade = grade.history[which.max(year)])
ОБНОВЛЕНИЕ 1: Я не уверен, что заставляет ваш код возвращать числовой код для каждого уровня, а не метку уровня. Это не просто проблема с функцией last
(вы можете видеть это, если вы делаете last(df$grade.history)
). Однако, если вы хотите отсортировать по метке времени, а затем вернуть последнюю строку, код ниже сохранит метки уровня. slice
возвращает строки, указанные вами в каждом значении ID
. В этом случае мы указываем последнюю строку, используя n()
, которая возвращает общее количество строк для каждого значения ID
.
df.summary <- df %>%
group_by(ID) %>%
slice(n())