5

我正在使用以下代码从日期(以 dd/mm/yyyy 形式)给我一周中的哪一天。

编辑:我上传了一个更相关的数据集。

df <- structure(list(Date = c("18/01/2013", "18/01/2013", "18/01/2013", 
                    "18/01/2013", "18/01/2013"), Time = c("07:25:30", "07:25:40", 
                                                          "07:25:50", "07:26:00", "07:26:10"), Axis1 = c(217L, 320L, 821L, 
                                                                                                         18L, 40L), Steps = c(6L, 7L, 5L, 1L, 1L), wday = c(7, 7, 7, 7, 7)), .Names = c("Date", "Time", "Axis1", "Steps", "wday"), row.names = 18154:18158, class = "data.frame")


library(lubridate)
df$wday = wday(df$Date)
df$wday.name = wday(df$Date, label = TRUE, abbr = TRUE)

然而,正如 R 报道的那样,18/1 是星期五而不是星期六。

有人对如何纠正这个问题有任何建议吗?

编辑:我试图遵循 Dirk 给出的建议......

as.POSIXlt(df[,1])$wday

...但这仍然意味着 18/1 是星期六。

我的时区是 GMT/UTC(英国夏令时 + 1),但是因为我只想 R 从日期列中读取(这只是 d/m/y),我想我不需要指定这个.. .

如何将正确的 wday 列添加到现有的 R 数据框中?(如之前在我的原始脚本中详述的那样)。我正在努力让建议的编码工作,因为我以错误的格式提供了数据框 - 道歉。

4

3 回答 3

6

您可以为此使用基本 R 函数。使用您的df对象:

 R> as.POSIXlt(df[,1])$wday  
 [1] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
 R> weekdays(as.Date(df[,1])) 
  [1] "Friday"   "Friday"   "Friday"   "Friday"   "Friday"
  [6] "Friday"   "Friday"   "Friday"   "Friday"   "Friday" 
 [11] "Friday"   "Friday"   "Friday"   "Friday"   "Saturday"  
 [16] "Saturday" "Saturday" "Saturday" "Saturday" 
 R>     

由于未指定 TZ,因此结束时会溢出到星期六。

如果你这样做

 R> df <- data.frame(Date=seq(as.POSIXct("05:00", format="%H:%M", tz="UTC"),
 +                  as.POSIXct("23:00", format="%H:%M", tz="UTC"), by="hours"))

然后

 R> table(weekdays(as.Date(df[,1], TZ="UTC")))

 Friday
    19
 R> 

我认为周五/周六错误也可能在 lubridate 下消失,但我倾向于为此使用基本 R 函数。

编辑:确认。

R> lubridate::wday(as.Date(df[,1]), label=TRUE) 
 [1] Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri Fri 
[15] Fri Fri Fri Fri Fri          
Levels: Sun < Mon < Tues < Wed < Thurs < Fri < Sat  
R>
于 2013-05-31T13:50:26.103 回答
3

我认为这里的问题很简单。'lubridate' 包正是为这种类型的工作而设计的,但问题中的问题似乎只是关于理解 'lubridate' 功能。

OP 看到奇怪结果的原因是“df”中的日期没有以明确的格式存储(单位的递减顺序)。这意味着当调用“wday”函数时,它应用了不正确的转换并误读了日期。

为了解决这个问题,OP已经添加了将字符串转换为日期的想法,这是完全正确的。然而,'as.POSIXlt' 函数是一个笨重的工具,而 'lubridate' 包已经有了答案:'dmy' 函数。这是它的工作原理:

df$wday <- wday(dmy(df$Date))
df$wday.name <- wday(dmy(df$Date), label=TRUE, abbr=TRUE)

我们在这里做一些非常简单的事情。我们首先将 'df$Date' 从一组字符串转换为一组日期。'dmy' 函数会自动解析字符串以查找日、月、年(因此是 dmy)。一旦我们有了正确格式的字符串,我们就可以正确使用“wday”函数了。

于 2013-06-11T17:28:04.357 回答
0

我认为 Dinre 的答案是最简单的 - 我发现使用 Dates 比 POSIX 更不容易出错 - 但这是在使用 Date 和 Time 列时获得正确结果的简单方法。

# Convert your Date variable into a proper Date class
# This is the base-R equivalent of Dinre's dmy()
df$Date2 <- as.Date(df$Date, format = "%d/%m/%Y")

# Paste it together with your Time into a POSIX variable with timezone
# I think "GB" is the correct timezone code for you, but not certain
df$datetime <- as.POSIXct(paste(df$Date2, df$Time), tz = "GB")

# Calculate weekday
wday(df$datetime, label = TRUE)

这样做的好处是您几乎可以将其df$datetime用于其他任何东西(例如绘图)并获得一致的结果。如果您真的只想使用日期,那么 Dinre 的答案就是您所需要的。

于 2013-06-11T18:35:14.223 回答