我正在处理一个名为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" ...
我已创建以下脚本来实现此目标,并且它是有效的。但是,使用R-Studio和R版本3.1.1,运行Windows 8.1的corei5处理器的PC上也运行效率非常低。 (我实际上不知道花了多长时间,我在几个小时后上床睡觉,并在七个小时后的早上完成了。)
我确信有一种更有效的方法来执行此操作,因此我不必在睡觉时继续运行这样的脚本,但我无法弄清楚它是什么。我非常感谢任何建议和帮助。
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以获得编程方面的帮助,这是我的第一个问题/帖子。感谢您提供有关如何使我的问题更易于理解和回答的任何反馈。
答案 0 :(得分:1)
基础R 解决方案。您可以order
数据,然后使用duplicated
选择所需的行。
# 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
答案 1 :(得分:1)
如果您想为每个studentID
选择一个SGBSTDN_TERM_CODE_EFF
行,那么您可以使用dplyr
执行library(dplyr)
df %>% group_by(studentID) %>% arrange(SGBSTDN_TERM_CODE_EFF) %>%slice(n())
行:
{{1}}