How do I find the last date on which the value increased in another column?

I have a data frame in R that looks something like this:

person  date         level
Alex    2007-06-01   3
Alex    2008-12-01   4
Alex    2009-12-01   3
Beth    2008-03-01   6
Beth    2010-10-01   6
Beth    2010-12-01   6
Mary    2009-11-04   9
Mary    2012-04-25   9
Mary    2013-09-10   10

      

First I sorted it by name "person" and second by "date".

I am trying to figure out when the last increase in "level" occurred for each person. Ideally, the output will look something like this:

person  date
Alex    2008-12-01
Beth    NA
Mary    2013-09-10

      

+3


source to share


3 answers


Using dplyr

library(dplyr)

dat %>% group_by(person) %>%
    mutate(inc = c(F, diff(level) > 0)) %>%
    summarize(date = last(date[inc], default = NA))

      



Yielding:

Source: local data frame [3 x 2]

  person       date
1   Alex 2008-12-01
2   Beth       <NA>
3   Mary 2013-09-10

      

+8


source


Try the data.table version:

library(data.table)
setDT(dat)[order(person),diff:=c(NA,diff(level)),by=person][diff>0,tail(.SD,1),by=person][,-c(3,4),with=F]
   person       date
1:   Alex 2008-12-01
2:   Mary 2013-09-10

      



If you also need to include na:

dd=setDT(dat)[order(person),diff:=c(NA,diff(level)),by=person][diff>0,tail(.SD,1),by=person][,-c(3,4),with=F]
dd2 =data.frame(unique(ddt[!(person %in% dd$person),,]$person),NA)
names(dd2) = c('person','date')
rbind(dd, dd2)
   person       date
1:   Alex 2008-12-01
2:   Mary 2013-09-10
3:   Beth         NA

      

+1


source


Base-R version using df dataframe:

sapply(levels(df$Person), function(p) {
    s <- df[df$Person==p,]
    i <- 1+nrow(s)-match(TRUE,rev(diff(s$Level)>0))
    ifelse(is.na(i), NA, as.character(s$Date[i]))
})

      

creates a named vector

        Alex         Beth         Mary 
"2008-12-01"           NA "2013-09-10"

      

It's easy to wrap this to create whatever output format you need:

last.level.up <- function(df) {
    data.frame(Date=sapply(levels(df$Person), function(p) {
        s <- df[df$Person==p,]
        i <- 1+nrow(s)-match(TRUE,rev(diff(s$Level)>0))
        ifelse(is.na(i), NA, as.character(s$Date[i]))
    }))
}

last.level.up(df)

           Date
Alex 2008-12-01
Beth       <NA>
Mary 2013-09-10

      

+1


source







All Articles