我有一个数据集,该数据集当前按学期列出学生信息(即201610、201620、201630、201640、201710等),后缀为10 =秋季,20 =冬季,30 =春季和40 =夏季。并非所有学生都必须列出所有术语。
我想做的是确定一个学生入学的第一学期,大概是秋季,即T1,随后的学期是T2,T3等。由于某些学生可能会参加冬季暑假,所以我会希望将其标识为T1_Winter,T2_Summer等。
我已经能够隔离出学生所注册的各个术语,并且能够将第一个,中间和最后一个术语标识为1、2、3等。但是,我无法管理围绕如何识别秋季和春季分别是1、2、3、4以及冬季和夏季以及1.5、2.5、3.5、4.5等的中间术语。
# Create the sample dataset
data <- data.frame(
ID = c(1, 1, 1, 2, 2, 2, 2),
RegTerm = c(201810, 201820, 201830, 201910, 201930, 201940, 202010))
)
# Isolate student IDs and terms
stdTerm <- subset(data, select = c("ID","RegTerm"))
# Sort according to ID and RegTerm
stdTerm <- stdTerm[
with(stdTerm, order(ID, RegTerm)),
]
# Remove duplicate combinations of ID and term
y <- stdTerm[!duplicated(stdTerm[c(1,2)]),]
# Create an index to identify the term number
# for which a student enrolled
library(dplyr)
z <- y %>%
arrange(ID, RegTerm) %>%
group_by(ID) %>%
mutate(StdTermIndex = seq(n()))
现在,它会将学生的所有术语的进度标识为1、2、3等,但不能将冬季和夏季作为中间术语。也就是说,如果某个学生在秋季和冬季入学,则冬季将显示为2,而春季将显示为3。
在提供的示例数据中,我希望学生ID 1将201810反映为1,201820反映为1.5,将201830反映为2,依此类推。我可以参考的任何建议或以前的代码来包裹我的代码。中间学期?
答案 0 :(得分:0)
我认为,执行此操作的一种好方法是将RegTerm列分为year
和suffix
,然后在拆分值后应用一些条件公式。
下面的代码可以做到这一点,我们只需要将其应用于整个列并进行一些重新调整即可。
paste(strsplit(as.character(201810), "")[[1]][1:4], collapse = ""))
# "2018"
paste(strsplit(as.character(201810), "")[[1]][5:6], collapse = ""))
# "10"
因此,要在数据框上使用lapply
之类的内容,然后取消列出结果并添加新列。之后,您可以将值更改为数字,然后在mutate函数中使用一些条件语句来设置中间值等。
z$year <- unlist(lapply(z$RegTerm, function(x) paste(strsplit(as.character(x), "")[[1]][1:4], collapse = "")))
z$suf <- unlist(lapply(z$RegTerm, function(x) paste(strsplit(as.character(x), "")[[1]][5:6], collapse = "")))
看起来有点难看,但是它所做的就是将RegTerm
分开,然后分别选择year和suf的前4个或后2个字符,然后折叠(使用collapse = ""
中的paste
)他们成一个字符串。我们将lapply
整列,然后将其取消列出以创建矢量。
我建议您理解此答案中的前两行代码,然后将其变得显而易见。
答案 1 :(得分:0)
因此,为了在您的示例中做到这一点,我创建了一个句柄变量,该变量告诉我RegTerm
是偶数还是奇数。
原因很简单,奇数RegTerm
表示它是一个常规术语,而偶数则是冬季或夏季术语。
library(dplyr)
data <- data.frame(
ID = c(1, 1, 1, 2, 2, 2, 2),
RegTerm = c(201810, 201820, 201830, 201910, 201930, 201940, 202010)
)
dat <- data %>%
mutate(term = str_extract(RegTerm, '(?<=\\d{4})\\d{1}(?=0)'),
term = as.numeric(term) %% 2) %>%
group_by(ID) %>%
mutate(numTerm = cumsum(term),
numTerm = ifelse(term == 0, numTerm + 0.5, numTerm))
第一个变异提取RegTerm
列中的第5个数字并将其除以2。如果等于1,则表示它是一个常规术语,否则将是夏季或冬季。
接下来,我将求和该变量的总和,这将为您提供学生所在的RegTerm
所在的位置。然后,我将每term == 0
加到numTerm
0.5中,以说明冬季和夏季的条件。
# A tibble: 7 x 4
# Groups: ID [2]
ID RegTerm term numTerm
<dbl> <dbl> <dbl> <dbl>
1 1 201810 1 1
2 1 201820 0 1.5
3 1 201830 1 2
4 2 201910 1 1
5 2 201930 1 2
6 2 201940 0 2.5
7 2 202010 1 3
这样,如果有一个学生从冬季学期开始,numTerm
将被分配一个0.5
的值,只有当他达到常规学期{{1}时才具有numTerm = 1
}