【问题标题】:POSIXct values become numeric in reshape2 dcastPOSIXct 值在 reshape2 dcast 中变为数字
【发布时间】:2012-08-30 15:53:56
【问题描述】:

我正在尝试使用最新的 包 (1.2.1) 中的 dcast 对 value.var 为 POSIXct 类型的数据帧(或 data.table)进行非规范化,但在生成的数据帧中,日期值已失去其 POSIXct 类并变为数字。

如果我希望将值恢复为 POSIXct 的值,我真的必须 as.POSIXct() 每个生成的列,还是我遗漏了什么?

x <- c("a","b");
y <- c("c","d");
z <- as.POSIXct(c("2012-01-01 01:01:01","2012-02-02 02:02:02"));
d <- data.frame(x, y, z, stringsAsFactors=FALSE);
str(d);
library(reshape2);
e <- dcast(d, formula = x ~ y, value.var = "z");
str(e);

运行上述语句的结果(注意新列 c 和 d 是数字纪元秒而不是 POSIXct):

> x <- c("a","b");
> y <- c("c","d");
> z <- as.POSIXct(c("2012-01-01 01:01:01","2012-02-02 02:02:02"));
> d <- data.frame(x, y, z, stringsAsFactors=FALSE);
> str(d);
'data.frame':   2 obs. of  3 variables:
 $ x: chr  "a" "b"
 $ y: chr  "c" "d"
 $ z: POSIXct, format: "2012-01-01 01:01:01" "2012-02-02 02:02:02"
> library(reshape2);
> e <- dcast(d, formula = x ~ y, value.var = "z");
> str(e);
'data.frame':   2 obs. of  3 variables:
 $ x: chr  "a" "b"
 $ c: num  1.33e+09 NA
 $ d: num  NA 1.33e+09

【问题讨论】:

  • 我很困惑。如果您添加新行,因此结果 data.frame 中没有 NA 值,则行为仍然存在,但是,相同的 acast 调用会给出预期的 POSIXct 结果。

标签: reshape2 r reshape2


【解决方案1】:

在转换/扩大数据集时对日期完整性进行预处理和/或后处理可能非常麻烦。

在这方面,除非您需要的重塑很复杂,否则 tidyr 包中的 pivot_wider() 尊重日期对象——在此过程中没有转换。此外,它可以更好地控制铸造/加宽过程,从而避免后处理步骤 (https://tidyr.tidyverse.org/reference/pivot_wider.html)。

【讨论】:

  • 不鼓励基于链接的答案:链接可能已损坏。你能考虑用直接解决问题的代码来充实你的答案吗?
【解决方案2】:

我也遇到了这个问题。我首先将日期字段强制转换为字符,然后 dcast,然后再转换回日期来解决它。

【讨论】:

    【解决方案3】:

    执行debug(dcast)debug(as.data.frame.matrix),然后逐步执行dcast() 调用启动的计算将显示as.data.frame.matrix() 中的这些行有问题:

    if (mode(x) == "character" && stringsAsFactors) {
        for (i in ic) value[[i]] <- as.factor(x[, i])
    }
    else {
        for (i in ic) value[[i]] <- as.vector(x[, i])
    }
    

    最新的 POSIXct 对象的模式为 "numeric",因此评估遵循第二个分支,它将结果转换为数字。

    如果您使用dcast(),您似乎需要对结果进行后处理,这应该不会太难如果您有正确的origin。像这样的东西(它不能完全得到 origin 正确)应该可以解决问题:

    e[-1] <- lapply(e[-1], as.POSIXct, origin="1960-01-01")
    

    FWIW,基本 R 的 reshape() 保留 POSIXct 值,但需要您编辑结果列的名称...

    reshape(d, idvar="x", timevar="y",  direction="wide")
    #   x                 z.c                 z.d
    # 1 a 2012-01-01 01:01:01                <NA>
    # 2 b                <NA> 2012-02-02 02:02:02
    

    【讨论】:

    • @josh-obrien:感谢您的快速响应和调试信息。所以罪魁祸首是as.vector,它只返回原子类型。最终我将使用data.table,因为我正在为数千列和数万行执行此操作,所以我会看看 lapply 语法是否会在那里做正确的事情。
    • 根据 Hadley 的要求报告了 here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    相关资源
    最近更新 更多