代码之家  ›  专栏  ›  技术社区  ›  Nathan123

如何根据一个逻辑值插入一个逻辑值,它是否有一个先前的值?

  •  1
  • Nathan123  · 技术社区  · 6 年前

    我有以下几点 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年级学生)

    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 回复  |  直到 6 年前
        1
  •  3
  •   Frank    6 年前

    可以使用联接来查找所需的行

    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]
    
        2
  •  0
  •   tblznbits    6 年前

    如果你愿意使用 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 ,所以我无法提供特定于该包的答案。