2012-02-09 2 views
152

Предположим, что у меня есть дата в R, и она отформатирована следующим образом.Найти день недели

date  
2012-02-01 
2012-02-01 
2012-02-02 

Есть ли способ в R добавить еще один столбец с днем ​​недели, связанным с датой? Набор данных действительно большой, поэтому было бы бессмысленно проходить вручную и вносить изменения.

df = data.frame(date=c("2012-02-01", "2012-02-01", "2012-02-02")) 

Таким образом, после добавления дней, он будет в конечном итоге выглядит как:

date  day 
2012-02-01 Wednesday 
2012-02-01 Wednesday 
2012-02-02 Thursday 

Возможно ли это? Может ли кто-нибудь указать мне на пакет, который позволит мне это сделать? Просто пытайтесь автоматически генерировать день по дате.

ответ

218
df = data.frame(date=c("2012-02-01", "2012-02-01", "2012-02-02")) 
df$day <- weekdays(as.Date(df$date)) 
df 
##   date  day 
## 1 2012-02-01 Wednesday 
## 2 2012-02-01 Wednesday 
## 3 2012-02-02 Thursday 

Edit: Просто, чтобы показать другой путь ...

wday компонент POSIXlt объекта Числовой будний день (0-6 начинающийся в воскресенье).

as.POSIXlt(df$date)$wday 
## [1] 3 3 4 

, которые вы могли бы использовать для подмножества символьного вектора названий дней недели

c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", 
    "Friday", "Saturday")[as.POSIXlt(df$date)$wday + 1] 
## [1] "Wednesday" "Wednesday" "Thursday" 
+2

+1 Есть ли способ использовать 'weekdays', чтобы получить число дней недели, как вы используете' as.POSIXlt' ?? – Shambho

+2

@Shambho Я думаю, вы могли бы это сделать: 'setNames (0: 6, c (« воскресенье »,« понедельник »,« вторник »,« среда »,« четверг »,« пятница »,« суббота »)) [будни (as.Date (ДФ дата $))] '. Если вам не нравятся имена, вы можете обернуть вокруг него 'noname()'. – GSee

+4

Чтобы получить день недели (0-6, Sun-Sat) с даты, которую вы можете сделать: format (as.Date (df $ date), "% w"). Подробные сведения о формате см. На странице http://www.stat.berkeley.edu/~s133/dates.html. – JStrahl

50

Посмотрите ?strftime:

df$day = strftime(df$date,'%A') 
+7

В случае, если кто-то искал в будний день онемели er - используйте ''% u'' вместо ''% A'' –

+0

Способ лучше верхнего ответа. Короткая и ясная. – wordsforthewise

33

Используйте lubridate пакет и функции wday:

library(lubridate) 
df$date <- as.Date(df$date) 
wday(df$date, label=TRUE) 
[1] Wed Wed Thurs 
Levels: Sun < Mon < Tues < Wed < Thurs < Fri < Sat 
+7

Хорошая вещь об этом подходе заключается в том, что он возвращает дни как фактор, поэтому, если вы создадите диаграмму, дни будут в правильном порядке. – bobfet1

10

Это должно сделать трюк

df = data.frame(date=c("2012-02-01", "2012-02-01", "2012-02-02")) 
dow <- function(x) format(as.Date(x), "%A") 
df$day <- dow(df$date) 
df 

#Returns: 
     date  day 
1 2012-02-01 Wednesday 
2 2012-02-01 Wednesday 
3 2012-02-02 Thursday 
15

Допустит, вы дополнительно хотите недели, чтобы начать на понедельник (вместо используемого по умолчанию в воскресенье), то следующий полезно:

require(lubridate) 
df$day = ifelse(wday(df$time)==1,6,wday(df$time)-2) 

Результатом являются дни в интервале [0, .., 6].

Если вы хотите, чтобы интервал будет [1, .. 7], используйте следующее:

df$day = ifelse(wday(df$time)==1,7,wday(df$time)-1) 

... или, в качестве альтернативы:

df$day = df$day + 1 
1

форма комментарий о JStrahl format(as.Date(df$date),"%w"), мы получим номер текущего дня: as.numeric(format(as.Date("2016-05-09"),"%w"))

1
start = as.POSIXct("2017-09-01") 
end = as.POSIXct("2017-09-06") 

dat = data.frame(Date = seq.POSIXt(from = start, 
            to = end, 
            by = "DSTday")) 

# see ?strptime for details of formats you can extract 

# day of the week as numeric (Monday is 1) 
dat$weekday1 = as.numeric(format(dat$Date, format = "%u")) 

# abbreviated weekday name 
dat$weekday2 = format(dat$Date, format = "%a") 

# full weekday name 
dat$weekday3 = format(dat$Date, format = "%A") 

dat 
# returns 
    Date  weekday1 weekday2 weekday3 
1 2017-09-01  5  Fri Friday 
2 2017-09-02  6  Sat Saturday 
3 2017-09-03  7  Sun Sunday 
4 2017-09-04  1  Mon Monday 
5 2017-09-05  2  Tue Tuesday 
6 2017-09-06  3  Wed Wednesday