我正在尝试使用最新的reshape2软件包(1.2.1)中的dcast来对数据框(或data.table)进行非规范化,其中value.var是POSIXct类型,但是在结果数据中框架,日期值已丢失其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
答案 0 :(得分:9)
执行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
答案 1 :(得分:0)
我刚遇到这个问题。我通过首先将日期字段强制转换为字符,然后转换为dcast,然后转换回日期来解决它。
答案 2 :(得分:0)
在投射/扩展数据集时进行日期完整性的预处理和/或后处理可能非常麻烦。
在这方面,除非您需要进行重塑,否则包 tidyr 中的 pivot_wider()尊重日期对象-途中没有转换。此外,它对投放/扩展过程提供了更多控制,从而避免了后期处理步骤(https://tidyr.tidyverse.org/reference/pivot_wider.html)。