Рассчитать номер недели (0-53) в год
У меня есть набор данных с местоположениями и датами. Я хотел бы рассчитать неделю года как номер (00-53), но использовать четверг в качестве первого дня недели. Данные выглядят следующим образом:
location <- c(a,b,a,b,a,b)
date <- c("04-01-2013","26-01-2013","03-02-2013","09-02-2013","20-02-2013","03-03-2013")
mydf <- data.frame(location, date)
mydf
Я знаю, что существует функция strftime для вычисления недели года, но можно использовать только понедельник или воскресенье в качестве первого дня недели.
Любая помощь будет высоко оценена.
Ответы
Ответ 1
Просто добавьте 4 к форматированным в дате значениям:
> mydf$Dt <- as.Date(mydf$date, format="%d-%m-%Y")
> weeknum <- as.numeric( format(mydf$Dt+3, "%U"))
> weeknum
[1] 1 4 5 6 7 9
Это использует соглашение о подсчете основанных на 0, так как это то, что предоставляет strftime, и мы просто соглашаемся с этой базой кода, поэтому первая пятница в году, которая начинается во вторник, как это было в 2013 году, будет 1-недельным результатом, Добавьте 1 к значению, если вы хотите использовать соглашение на основе 1. (По существу, значения, формируемые по дате, находятся в целочисленной последовательности из "источника", поэтому они действительно не распознают годы или недели. Добавление 4 просто сдвигает опорный фрейм базового целого числа Date.)
Изменить примечание. Изменено, чтобы добавить три стратегии по рекомендации Габора..... который по-прежнему не рассматривает вопрос о том, как бороться с прошлой неделей предыдущего года.
Ответ 2
Поскольку вопрос гласит, что неделя идет от 00-53, мы предполагаем, что число недели - это число четвергов в году на или до указанной даты. Таким образом, первый четверг в году начинается неделя 1, а неделя 0 назначается за все дни до этого.
(Были комментарии, что если в первый день года был вторник, то это будет неделя 1, но если бы это было так, то никогда не могло быть недели 0, как кажется в этом вопросе, поэтому некоторые разъяснения о том, что именно может потребоваться определение номера недели. Здесь мы будем использовать определение в предыдущем абзаце, но изменить его было бы непросто, если бы мы знали, что такое определение. Например, если бы мы всегда хотели, чтобы первая неделя в год равен 1, даже если это была короткая неделя, тогда мы могли бы добавить !is.thu(jan1(d))
к результату.)
Оба из приведенных ниже решений достаточно коротки, чтобы они могли быть выражены в одном утверждении; однако для ясности мы каждый раз приводили их в несколько коротких функций. Первый особенно прямолинейный, но второй автоматически векторизован без необходимости и, вероятно, будет более эффективным.
1. сумма четверга в году. Это решение предполагает, что вход d
имеет класс "Date"
и просто суммирует число четвергов за год до или на нем:
is.thu <- function(x) weekdays(x) == "Thursday"
jan1 <- function(x) as.Date(cut(x, "year"))
week4 <- function(d) {
sapply(d, function(d) sum(is.thu(seq(jan1(d), d, by = "day"))))
}
Мы можем проверить это следующим образом:
d <- as.Date(c("2013-01-04", "2013-01-26", "2013-02-03", "2013-02-09",
"2013-02-20", "2013-03-03"))
week4(d) # 1 4 5 6 7 9
2. nextthu
На основе функции nextfri
в зоопарке quickref vignette мы видим, что количество дней с Эпохи (1970-01-01) ) следующего четверга (или день, о котором идет речь, если его уже четверг), как указано в nextthu
в первой строке ниже. Применяя это к первому дню года, мы получаем результат, где d
по-прежнему:
nextthu <- function(d) 7 * ceiling(as.numeric(d) / 7)
week4a <- function(d) (as.numeric(d) - nextthu(jan1(d))) %/% 7 + 1
и вот тест
week4a(d) # 1 4 5 6 7 9
ADDED: исправлена ошибка во втором решении.