如何创建一个空的 POSIXct 向量

32

我想创建一个空的POSIXct向量,以便在其中放入一个POSIXct

vec <- vector("POSIXct", 10)
vec
vec[1] <- "2014-10-27 18:11:36 PDT"
vec

那个方法不起作用。有任何想法吗?


9
我是一个支持将值初始化为 NA 的粉丝,例如 as.POSIXct(rep(NA, 10)) - Gregor Thomas
@Gregor - 你想把那个作为答案发布吗?关于对结果进行数学运算的有效担忧是存在的。 - Rich Scriven
7个回答

28

由于没有 POSIX mode,你不能仅使用 vector() 初始化一个 POSIXct 向量(请参阅 ?mode 获取所有模式类型的列表)。

但我们可以使用 .POSIXct 从字符向量创建向量。

(x <- .POSIXct(character(10))) ## the same as .POSIXct(vector("character", 10))
# [1] NA NA NA NA NA NA NA NA NA NA
class(x)
# [1] "POSIXct" "POSIXt" 

请注意,您还可以使用.POSIXct(integer(10))来生成一个长度为10的原始日期时间向量。


1
这是我以前从未尝试过的东西。有趣!+1 - jazzurro
2
这很简洁,但它依赖于.POSIXct中的解析错误。更简单(可能更清晰)的方法是使用.POSIXct(rep(NA, 10)) - user295691
1
解析掉落?不确定什么意思,.POSIXct()只是使用structure()。有很多方法。您还可以执行.POSIXct(NA [1:10]) - Rich Scriven
2
通过解析fallthrough,我的意思是character(10)会生成一个包含10个空字符串的向量,而不是10个NA,所以结果结构之所以有效是因为“”被打印为NA。 rep解决方案生成逻辑向量,这将被提升为数字。这意味着像x + 3600这样的操作将产生奇怪的错误。 - user295691
3
对于未来的观众,我将指出我确实包括了.POSIXct(integer(10)),尽管在答案中没有明确说明,它可以用于数学运算。 - Rich Scriven
显示剩余2条评论

11

我通常将事物初始化为NA

as.POSIXct(rep(NA, 10))

在这种情况下表现良好。它明确地执行了@RichardScriven答案中在幕后发生的事情 - 请参阅那里的评论以获得更长的讨论。


6
这个问题有一个非常简单的答案!
使用lubridate,你只需要简单地写,例如:empty_df <- tibble(date = POSIXct())

1
当以以下方式创建POSIXct向量时,底层类型将变为double:
> times <- as.POSIXct(c("2015-09-18 09:01:05.984 CEST", "2015-09-18 10:01:10.984 CEST", "2015-09-18 10:21:20.584 CEST"))
> typeof(times)
[1] "double"
> values <- c(5,6,7)

将上述向量与一个以字符为基础类型初始化的空的POSIXct向量相结合,结果是一个字符-POSIXct向量:
> tm1 <- c(.POSIXct(character(0)), times)
> typeof(tm1)
[1] "character"

"

...无法直接绘制:

"
> ggplot() + geom_line(aes(x=tm1, y=val), data=data.frame(tm1,val))
geom_path: Each group consist of only one observation. Do you need to adjust the group aesthetic?

因此,我更喜欢使用双精度或整数作为底层类型来初始化我的空的POSIXct向量:
> tm2 <- c(.POSIXct(double(0)), times)
> typeof(tm2)
[1] "double"
> ggplot() + geom_line(aes(x=tm2, y=val), data=data.frame(tm2,val))

Simple POSIXct plot

> tm3 <- c(.POSIXct(integer(0)), times)
> typeof(tm3)
[1] "double"
> ggplot() + geom_line(aes(x=tm3, y=val), data=data.frame(tm3,val))
#Same thing...

当使用double时,向量也会初始化为有效日期(这可能是可取的,也可能不是):
> .POSIXct(character(10))
 [1] NA NA NA NA NA NA NA NA NA NA
> .POSIXct(double(10))
 [1] "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET"
 [7] "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET"

1
我会选择 Gregor的解决方案。起初我使用了 Rich Scriven的解决方案,但后来在尝试计算非 NA 元素的差异时出现了错误,如下面的示例所示。
t1 <- as.POSIXct("2014-10-27 18:11:36 PDT")
t2 <- as.POSIXct("2014-11-20 18:11:36 PDT")
x <- .POSIXct(character(10))
x[1] <- t1

difftime(t2, t1)
#R Time difference of 24 days

# fails
difftime(t2, x[1])
#R Error in unclass(time1) - unclass(time2) : 
#R   non-numeric argument to binary operator

unclass(x[1]) # character
#R [1] "1414429896"
unclass(t1)
#R [1] 1414429896
#R attr(,"tzone")
#R [1] ""

x <- .POSIXct(rep(NA_real_, 10))
x[1] <- t1
difftime(t2, x[1]) # all good
#R Time difference of 24 days

这甚至可能导致像这个一样的奇怪错误,需要花费一些时间才能发现。
t1 <- as.POSIXct("2001-07-24 CEST")
t2 <- as.POSIXct("2002-08-29 CEST")
x <- .POSIXct(character(10))
x[1] <- t1

t2 < t1
#R [1] FALSE
t2 < x[1] # oh boy 
#R [1] TRUE

# the reason (I think)
unclass(t2)
#R [1] 1030572000
#R attr(,"tzone")
#R [1] ""
unclass(x[1])
#R [1] "995925600"

"995925600" > 1030572000
#R [1] TRUE

0
我使用以下函数来实现此功能。与其他解决方案非常相似。
vector_datetime <- function(n = 0L) structure(rep(NA_integer_, n), class = c("POSIXct", "POSIXt"))

这样你就可以做类似的事情。

> vector_datetime()
POSIXct of length 0

> vector_datetime(10)
 [1] NA NA NA NA NA NA NA NA NA NA

> class(vector_datetime(10))
[1] "POSIXct" "POSIXt" 

这也可以使用 lubridate 完成。

library(lubridate)

> as_datetime(integer(0))
POSIXct of length 0

0

也许我错过了上面的内容,但这是一个真正空的POSIXct:

as.POSIXct(integer())

例如,如果您想要一个空的数据框:
empty <- data.frame(date_time = as.POSIXct(integer()),
                    date = as.Date(x = integer(), origin = "1970-01-01"))
empty
[1] date_time date     
<0 rows> (or 0-length row.names)

str(empty)
'data.frame':   0 obs. of  2 variables:
 $ date_time: 'POSIXct' num(0) 
 - attr(*, "tzone")= chr ""
 $ date     : 'Date' num(0) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接