r-根据数据帧列中的参数使用dplyr::mutate和lubridate::force_tz



我正在尝试使用lubridate::force_tz将时区信息添加到格式化为字符串(如.character())的时间戳(日期+时间)中。两者都存储为数据帧中的两列:

require(lubridate)
require(dplyr)
row1<-c(as.character(now()),"Etc/UTC")
row2<-c(as.character(now()+5),"America/Chicago")
df<-as.data.frame(rbind(row1,row2))
names(df)<-c("dt","tz")
x<-force_tz(as.POSIXct(as.character(now())),"Etc/UTC") #works
df<-df%>%mutate(newDT=force_tz(as.POSIXct(dt),tz)) #fails

我得到:UseMethod中的错误("mute_"):没有适用于类"c('matrix','character')"对象的"mutate_"方法

根据Stibu的评论,我尝试了一种迭代的(类似un-R的)方法:

for (i in seq(from=1,to=length(df$dt))){
timestamp<-as.character(df[i,1])
tz<-as.character(df[i,2])
print(tz)
newdt<-force_tz(as.POSIXct(timestamp),tz)
df[i,3]<-newdt
print(attr(df[i,3],"tzone"))
df$timezone<-attr(df[i,3],"tzone")
}

这样可以正确地提取值,但似乎会将tz的值设置为遇到的第一个值——奇怪的是:

[1] "Etc/UTC"
[1] "Etc/UTC"
[1] "America/Chicago"
[1] "Etc/UTC"

我本以为最后一次打印输出会产生"America/Chicago"df看起来像:

 > df
               dt              tz               newDT timezone
 1 2016-04-13 23:07:45         Etc/UTC 2016-04-13 23:07:45  Etc/UTC
 2 2016-04-13 23:07:50 America/Chicago 2016-04-14 04:07:50  Etc/UTC

您的代码中实际上有两个问题,我将在下面分别讨论。

dplyr处理数据帧

您的df是一个矩阵,而不是一个数据帧。但是mutate()(以及dplyr的函数)适用于数据帧。错误消息只是简单地告诉您mutate()不知道如何处理矩阵。

您可以通过将df转换为数据帧来解决此问题:

df <- as.data.frame(df)
names(df)<-c("dt","tz")

关于names()的备注:此函数可用于获取/设置数据帧的列名。对于矩阵,对应的函数是colnames()。您在矩阵上使用了names(),它没有设置矩阵的列名。因此,在转换之后也不设置数据帧的名称。

您也可以从一开始创建一个数据帧,如下所示:

df <- data.frame(dt = as.character(c(now(), now() + 5)),
                 tz = c("Etc/UTC", "America/Chicago"),
                 stringsAsFactors = FALSE)

请注意,您需要按列定义内容,而不是像以前那样按行定义内容。

如果使用数据帧df,则mutate()不会出现错误。

每个矢量一个时区

不幸的是,还有第二个问题。你想做的事根本做不到。原因如下。

让我们用时区CET:将df的第一列转换为POSIXct

ts <- as.POSIXct(df$dt, tz = "CET")
ts
## [1] "2016-04-13 14:42:26 CEST" "2016-04-13 14:42:31 CEST"

让我们试着用两个时区做同样的事情:

ts <- as.POSIXct(df$dt, tz = c("CET", "UTC"))
## Error in strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", tz = tz) : 
##   invalid 'tz' value

这不起作用。原因是每个向量有一个单个时区,而不是向量中每个元素都有一个时区。查看ts:的属性

attributes(ts)
## $class
## [1] "POSIXct" "POSIXt" 
## 
## $tzone
## [1] "CET"

时区被设置为整个向量的属性,而不是每个元素的属性。

相关内容

  • 没有找到相关文章