如何基于是否具有先前值插入逻辑值?

时间:2018-09-26 19:41:50

标签: r data.table

我有以下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

2 个答案:

答案 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=anycumsum来完成,但是我认为效率较低:

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并不熟悉,所以我无法提供特定于该软件包的答案。