【问题标题】:Replacing column values with a POSIXlt object用 POSIXlt 对象替换列值
【发布时间】:2013-10-04 07:27:50
【问题描述】:

考虑以下 R 代码,它将数据框的一列中的值替换为一组 POSIXct 值:

foo <- as.data.frame(list(bar=rep(5,5)))
bar <- as.POSIXct(rep(5,5), origin="1970-1-1", tz="c")
foo[,1] <- bar

我的问题:为什么当我尝试使用 POSIXlt 时相同的操作会失败?例如:

foo <- as.data.frame(list(bar=rep(5,5)))
bar <- as.POSIXlt(rep(5,5), origin="1970-1-1", tz="c")
foo[,1] <- bar
Warning message:
   In `[<-.data.frame`(`*tmp*`, , 1, value = list(sec = c(5, 5, 5,  :
   provided 9 variables to replace 1 variables

此外,如果我按名称而不是索引来引用列,那么相同的分配就可以正常工作:

foo$bar <- bar
foo <- as.data.frame(list(bar=rep(5,5)))
bar <- as.POSIXlt(rep(5,5), origin="1970-1-1", tz="c")
foo$bar <- bar

我错过了什么?

【问题讨论】:

  • 我收到警告说我的系统上的时区“c”是未知的。
  • Roman:我没有收到警告。 “c”应指当前时区。我想你可以指定UCT吗?还是您当地的时区?

标签: r dataframe assign posixct


【解决方案1】:

来自help("[.data.frame")

对于 [ 的替换值可以是一个列表:列表的每个元素都是 用于替换(部分)一列,必要时回收列表。

所以你可以这样做:

df <- data.frame(a=1:2)
df[,2:3] <- list(3:4, 5:6)
#  a V2 V3
#1 1  3  5
#2 2  4  6

但是,这会导致警告:

df[,4] <- list(7, 8)
# Warning message:
#   In `[<-.data.frame`(`*tmp*`, , 4, value = list(7, 8)) :
#   provided 2 variables to replace 1 variables
#   a V2 V3 V4
# 1 1  3  5  7
# 2 2  4  6  7

现在POSIXlt 对象是一个包含 9 个元素的列表:

unclass(rep(as.POSIXlt(Sys.time()), 2))
# $sec
# [1] 1.958244 1.958244
# 
# $min
# [1] 54 54
# 
# $hour
# [1] 10 10
# 
# $mday
# [1] 4 4
# 
# $mon
# [1] 9 9
# 
# $year
# [1] 113 113
# 
# $wday
# [1] 5 5
# 
# $yday
# [1] 276 276
# 
# $isdst
# [1] 1 1
# 
# attr(,"tzone")
# [1] ""     "CET"  "CEST"

使用[&lt;-.data.frame 将此列表分配给一列会给出您观察到的警告。

问题的潜在解决方案很简单:

  • 使用POSIXct 并避免使用POSIXlt。使用后者的唯一原因是需要提取一些列表组件,这种情况并不常见(您始终可以强制转换为 POSIXlt,例如,用于舍入时间值的内部函数)。
  • 使用$&lt;-.data.frame。这在交互式使用之外通常很麻烦。
  • POSIXlt 对象包装在list 中以进行赋值:df[,1] &lt;- list(POSIXlt_object)

【讨论】:

    【解决方案2】:

    POSIXlt 对象似乎是列表,有 9 个条目。

    unlist(as.POSIXlt(5, origin="1970-1-1"))
    sec   min  hour  mday   mon  year  wday  yday isdst 
      5     0     1     1     0    70     4     0     0
    
    unlist(as.POSIXct(5, origin="1970-1-1"))
    [1] "1970-01-01 00:00:05 CET"
    

    显然,由于 POSIXlt 对象未列出,因此对 data.frame 的分配失败。

    foo <- as.data.frame(list(bar=rep(5,5)))
    bar <- as.POSIXlt(rep(5,5), origin="1970-1-1", tz="")
    foo[,1] <- bar   # this fails
    foo[,1:9] <- bar # this works
    

    另一方面,分配给列表是有效的。

    foo <- as.data.frame(list(bar=rep(5,5)))
    bar <- as.POSIXlt(rep(5,5), origin="1970-1-1", tz="")
    foo[[1]] <- bar  # or foo$bar <- bar
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-23
      • 2023-02-25
      • 1970-01-01
      • 2015-01-01
      • 2019-09-17
      • 2020-02-08
      • 2017-05-29
      相关资源
      最近更新 更多