我正在使用一个名为 Student_Majr2 的数据框,其中包含大约 60K 行和两个相关列:一个用于匿名学生 ID 号,另一个用于学生申报专业的日期/学期(下面的前两列)。问题是大量学生改变专业,因此对于每个学生 ID 可能有多个关联日期。大约有 30,000 个唯一的学生 ID。我的目标是创建一个新的数据框,其中仅包含每个学生 ID 的最新专业声明日期(即他们最终选择的专业)。这是数据框的结构:
'data.frame': 59749 obs. of 5 variables:
$ studentID : int 1 2 2 2 4 4 5 6 8 8 ...
$ SGBSTDN_TERM_CODE_EFF : int 199920 199920 200040 200320 200130 200220 200140 200020 200430 200540 ...
$ SGBSTDN_MAJR_CODE_1 : chr "720" "966" "996" "906" ...
$ SGBSTDN_MAJR_CODE_CONC_1: chr "" "" "" "" ...
$ SGBSTDN_LEVL_CODE : chr "UG" "UG" "UG" "UG" ...
我创建了以下脚本来实现此目标,并且它是有效的。然而,它的效率也非常低,在运行 Windows 8.1 的 corei5 处理器的 PC 上,使用 R-Studio 和 R 版本 3.1.1 运行需要几个小时。 (我实际上不确定花了多长时间,几个小时后我就上床 sleep 了,七个小时后早上就完成了)。
我确信有一种更有效的方法来执行此操作,因此我不必在 sleep 时继续运行这样的脚本,但我不知道它是什么。我将非常感谢任何建议和帮助。
library(dplyr)
final_majr <- data.frame() # the final dataframe with final major per student ID
tbl_df(final_majr)
students <- unique(Student_Majr2$studentID) #students gets vector with all unique student ids
for (i in students) { #loop through all student id numbers
temp_majr <- data.frame() #set up temporary dataframe for each unique student id and major
tbl_df(temp_majr)
for (q in 1:nrow(Student_Majr2)) { #loop through all row numbers from student_major df
if (Student_Majr2$studentID[q] == i){ #identify rows for each student ID from top loop
temp_majr <- rbind(temp_majr, Student_Majr2[q, ]) #and add to temp_majr df
}
}
temp_majr <- arrange(temp_majr, SGBSTDN_TERM_CODE_EFF) #order the rows using dplyr package
m <- nrow(temp_majr) # m gets the total number of rows in temp_majr
final_majr <- rbind(final_majr, temp_majr[m, ]) #and here we add the bottom row to final_majr
}
非常感谢您对此脚本的所有帮助。我经常咨询 stackoverflow 寻求编程帮助,这是我的第一个问题/帖子。感谢您提供有关如何使我的问题更容易理解和回答的反馈。
最佳答案
基础 R 解决方案。您可以对数据进行排序
,然后使用重复
来选择所需的行。
# some data
dat <- data.frame(studentID = c(1, 2, 2, 2, 4, 4, 5, 6, 8, 8),
SGBSTDN_TERM_CODE_EFF = c(199920, 199920, 200040, 200320, 200130, 200220, 200140, 200020, 200430, 200540),
SGBSTDN_MAJR_CODE_1 = letters[1:10])
# order data by id and latest date first
dat <- with(dat, dat[order(studentID, -SGBSTDN_TERM_CODE_EFF), ])
# select first observation
with(dat, dat[!duplicated(studentID), ])
# studentID SGBSTDN_TERM_CODE_EFF SGBSTDN_MAJR_CODE_1
# 1 1 199920 a
# 4 2 200320 d
# 6 4 200220 f
# 7 5 200140 g
# 8 6 200020 h
# 10 8 200540 j
关于R:对一列中与同一数据框中不同列中的特定值相对应的值进行排序/选择的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28784963/