【问题标题】:lubridate errors in R润滑R中的错误
【发布时间】:2013-05-31 13:42:03
【问题描述】:

我正在使用以下代码从某个日期(以 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 数据框中? (如之前在我的原始脚本中详述的那样)。我正在努力让建议的编码工作,因为我以错误的格式提供了数据框 - 道歉。

【问题讨论】:

  • 您的时区是 BST (+0100),而不是 GMT/UTC (+0000)。时区使用不一致有时会导致日期或工作日出现错误

标签: r timezone posixct lubridate


【解决方案1】:

您可以为此使用基本 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>

【讨论】:

  • 非常感谢@Dirk Eddelbuettel。抱歉,但我的原始数据框格式错误,我仍然遇到问题。任何帮助将不胜感激......
  • 我增加了赏金,因为使用我的新数据框,我仍在努力寻找解决方案。不过,我要感谢 @Dirk Eddelbuettel 迄今为止对我的问题的帮助。
【解决方案2】:

我认为这里的问题很简单。 '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' 函数会自动解析字符串以查找日、月、年(因此是 d-m-y)。一旦我们有了正确格式的字符串,我们就可以正确使用“wday”函数了。

【讨论】:

    【解决方案3】:

    我认为 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 的答案就是你所需要的。

    【讨论】:

    • 这是我使用的时区缩写列表:en.wikipedia.org/wiki/List_of_zoneinfo_time_zones
    • 我建议你看看'lubridate'包,如果你还不熟悉的话,Matt。我曾经一直使用基本的 R 函数,直到我发现了“lubridate”。它具有完全相同的功能,但具有非常简洁的包装器,可以为我节省大量时间。我现在完全皈依了,我衷心推荐它。当然,基本函数做同样的事情,所以你的输出不会有任何不同,只是你的代码。
    • @Dinre 感谢您的建议 - 我一直使用 lubridate 进行更高级别的日期操作,但我仍然喜欢使用基本函数来转换类型 - 部分原因是我想坚持我的了解%d/%m/%Y风格的格式代码,以防我遇到真正纠结的事情。
    猜你喜欢
    • 1970-01-01
    • 2020-11-10
    • 2021-06-08
    • 1970-01-01
    • 2018-08-21
    • 2020-06-04
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    相关资源
    最近更新 更多