我有以下data.frame
名学生参加了特定计划
library(data.table)
f.name<-c('a','a','b','b','b','c','c')
year<-c(2014,2015,2013,2014,2015,2015,2016)
grade<-c(9,10,8,9,10,7,8)
f.name<-as.character(f.name)
df.have<-data.frame(f.name,year,grade)
df.have
我对2014年加入特定计划的9年级学生特别感兴趣。但是,我想区分2014年首次加入该计划的9年级学生和返回该计划的9年级学生(谁是2013年的8年级学生)
我能够创建专栏来区分以下列方式在2014年首次加入该计划的9年级学生
df.have$new.students<-with(df.have, rowid(f.name) == 1 & year == 2014 & grade == 9)
df.have
f.name year grade new.students
1 a 2014 9 TRUE
2 a 2015 10 FALSE
3 b 2013 8 FALSE
4 b 2014 9 FALSE
5 b 2015 10 FALSE
6 c 2015 7 FALSE
7 c 2016 8 FALSE
如何创建另一列来标记回国学生。那些在2013年上8年级并在2014年返回的人?看起来像这样
f.name year grade new.student returning.students
1 a 2014 9 TRUE FALSE
2 a 2015 10 FALSE FALSE
3 b 2013 8 FALSE FALSE
4 b 2014 9 FALSE TRUE
5 b 2015 10 FALSE FALSE
6 c 2015 7 FALSE FALSE
7 c 2016 8 FALSE FALSE
答案 0 :(得分:3)
您可以使用联接来查找所需的行
library(data.table)
setDT(df.have)
# initialize to FALSE
df.have[, rs := FALSE]
# update to TRUE if the desired row is found
df.have[year == 2014 & grade == 9, rs :=
df.have[replace(copy(.SD), c("year", "grade"), list(2013, 8)), on=.(f.name, year, grade), .N, by=.EACHI]$N > 0L
]
这可以通过by=
和any
或cumsum
来完成,但是我认为效率较低:
df.have[, v :=
year == 2014 & grade == 9 & any(year == 2013 & grade == 8)
, by=f.name]
# or...
df.have[order(year), v :=
year == 2014 & grade == 9 & cumsum(year == 2013 & grade == 8)
, by=f.name]
答案 1 :(得分:0)
如果您愿意使用dplyr
,则可以使用group_by
来使用,并利用row_number()
功能。
library(dplyr)
df.have %>%
group_by(f.name) %>%
mutate(new_student = (grade == 9 & year == 2014 & row_number() == 1),
returning_student = (grade == 9 & year == 2014 & row_number() > 1)) %>%
ungroup()
f.name year grade new_student returning_student
<fct> <dbl> <dbl> <lgl> <lgl>
1 a 2014 9 TRUE FALSE
2 a 2015 10 FALSE FALSE
3 b 2013 8 FALSE FALSE
4 b 2014 9 FALSE TRUE
5 b 2015 10 FALSE FALSE
6 c 2015 7 FALSE FALSE
7 c 2016 8 FALSE FALSE
不幸的是,我对data.table
并不熟悉,所以我无法提供特定于该软件包的答案。