R中的重复错误

时间:2013-05-31 13:42:03

标签: r timezone posixct lubridate

我使用以下代码给我一个日期的星期几(格式为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数据帧中? (如我原来的脚本中所述)。我正在努力使建议的编码工作,因为我以错误的格式给出了数据帧 - 道歉。

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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'函数自动解析字符串,查找日,然后是月,然后是年(因此d-m-y)。一旦我们得到了正确格式的字符串,我们就可以正确使用'wday'功能。

答案 2 :(得分: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的答案就是你所需要的。