验证日期顺序是否正确

时间:2019-03-25 22:28:55

标签: r date sequence

我有一个包含4列日期的数据框。应该是col1首先出现,col2第二出现,col3第三出现,而col4最后出现。想要确定哪些行的日期不按顺序排列

这是一个玩具数据框

col1 <- c(as.Date("2004-1-1"), as.Date("2005-1-1"), as.Date("2006-1-1"))
col2 <- c(as.Date("2004-1-2"), as.Date("2005-1-3"), as.Date("2006-1-2"))
col3 <- c(as.Date("2004-1-5"), as.Date("2005-1-9"), as.Date("2006-1-19"))
col4 <- c(as.Date("2004-1-9"), as.Date("2005-1-15"), as.Date("2006-1-10"))
dates <- data.frame(col1, col2, col3, col4)

dates

    col1       col2       col3       col4
1 2004-01-01 2004-01-02 2004-01-05 2004-01-09
2 2005-01-01 2005-01-03 2005-01-09 2005-01-15
3 2006-01-01 2006-01-02 2006-01-19 2006-01-10

我想要的输出将是

    col1       col2       col3       col4       Seq?
1 2004-01-01 2004-01-02 2004-01-05 2004-01-09    T
2 2005-01-01 2005-01-03 2005-01-09 2005-01-15    T
3 2006-01-01 2006-01-02 2006-01-19 2006-01-10    F

3 个答案:

答案 0 :(得分:6)

我可以想到几个解决方案。我天真的建议将apply?is.unsorted一起使用,即:

  

测试对象是否未排序(以递增顺序),而没有   排序费用。

!apply(dates, 1, is.unsorted)
#[1]  TRUE  TRUE FALSE

否则,将其转换为长集,然后进行分组操作,这对于较大的数据集应该更快:

tmp <- cbind(row=seq_len(nrow(dates)), stack(lapply(dates, as.vector)))
!tapply(tmp$values, tmp$row, FUN=is.unsorted)

最后,通过Map比较每一列与下一列的蛮力方法,这应该会更快:

Reduce(`&`, Map(`<`, dates[-length(dates)], dates[-1]))

答案 1 :(得分:4)

一个简单的apply语句就能解决问题:

dates$Seq <- apply(dates, 1, function(x) all(x == sort(x)))

答案 2 :(得分:2)

rowSums(Reduce(pmax, dates, accumulate = TRUE) == dates) == NCOL(dates)
#[1]  TRUE  TRUE FALSE

Reducepmax标识每一行的连续最大日期。使用accumulate = TRUE,我们为每次迭代保留Reduce的输出,并与dates

中的原始数据进行比较

如果日期未排序,则引入NA的另一种方法。

!is.na(Reduce(function(x, y) ifelse(x > y | is.na(x), NA, y), dates))
[1]  TRUE  TRUE FALSE