Убедитесь, что последовательность дат находится в правильном порядке - PullRequest
3 голосов
/ 26 марта 2019

У меня есть фрейм данных, который имеет 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 ]

6 голосов
/ 26 марта 2019

Я могу придумать пару решений.Наивно я бы предложил использовать 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]))
4 голосов
/ 26 марта 2019

Простое утверждение apply поможет:

dates$Seq <- apply(dates, 1, function(x) all(x == sort(x)))
2 голосов
/ 26 марта 2019
rowSums(Reduce(pmax, dates, accumulate = TRUE) == dates) == NCOL(dates)
#[1]  TRUE  TRUE FALSE

Reduce с pmax определяет последовательную максимальную дату для каждой строки. С accumulate = TRUE мы сохраняем вывод Reduce для каждой итерации и сравниваем с исходными данными в dates

Другой подход, который вводит NA, если даты не отсортированы.

!is.na(Reduce(function(x, y) ifelse(x > y | is.na(x), NA, y), dates))
[1]  TRUE  TRUE FALSE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...