我有大量的NetCDF文件,其中包含按月平均的历史天气数据。时间维度单位为“自1600-01-01起的天数”,并使用360天日历。我使用了PCICt软件包来根据360天日历正确格式化时间维度。我的问题是:
尝试将数据写入数据帧或将其保存到输出文件时,收到以下错误消息:as.data.frame.default(x [[i]],optional = TRUE)中的错误:无法强制类“ “ PCICt”“到data.frame
我可以从该PCICt数据中提取年份和月份吗?
任何帮助将非常感激。
#packages used
require("PCICt")
require("RNetCDF")
#dput output assigned to "ex" variable (units "Days since 1600-01-01")
ex <- structure(c(1095, 1125, 1155, 1185, 1215, 1245, 1275, 1305, 1335,
1365, 1395, 1425), .Dim = 12L)
#used PCICt to correctly format date stamp
cal <- "360_day"
origin <- ("1600-01-01")
seconds.per.day <- 86400
origin.pcict <- as.PCICt(origin,cal)
ex_pcict <- origin.pcict + (ex * seconds.per.day)
#result of PCICt code
> print(ex_pcict)
[1] "1603-01-16" "1603-02-16" "1603-03-16" "1603-04-16"
[5] "1603-05-16" "1603-06-16" "1603-07-16" "1603-08-16"
[9] "1603-09-16" "1603-10-16" "1603-11-16" "1603-12-16"
#class definition
> class(ex_pcict)
[1] "PCICt"
#attempt to write to data.frame and resulting error message
> data.frame(date = ex_pcict)
Error in as.data.frame.default(x[[i]], optional = TRUE) :
cannot coerce class ""PCICt"" to a data.frame
Run Code Online (Sandbox Code Playgroud)
[解决]在解决我的问题后,今天早上我来到办公室,开始进行班级转换,最终得到了一个我可以使用的约会班级:
ex_char <- as.character.PCICt(ex_pcict)
ex_date <- as.Date(ex_char)
Run Code Online (Sandbox Code Playgroud)
然后,我可以将“ ex_date”写入data.frame并导出为.txt文件。我还使用as.numeric(format(ex_date,“%m”)和“%Y”分别提取月份和年份。
也许这个答案有点晚了,但有一种新的方法来处理这个问题。
大多数气候观测和预测数据均使用 CF 元数据约定进行格式化,使用时间坐标定义来格式化观测/预测的时间戳。您的数据有很多暗示表明您的数据确实属于这种情况。现在CRAN上有CFtime包。该包可以透明地处理所有 CF 日历:
install.packages("CFtime")
library(CFtime)
# Using your example
cf <- CFtime("days from 1600-01-01", "360_day",
c(1095, 1125, 1155, 1185, 1215, 1245, 1275, 1305, 1335,
1365, 1395, 1425))
# In a CF-compliant file you would read this straight out of your netCDF file
nc <- nc_open("my_data_file.nc")
cf <- CFtime(nc$dim$time$units, nc$dim$time$calendar, nc$dim$time$vals)
# Make a data.frame of the dates as string
data.frame(date = CFtimestamp(cf))
Run Code Online (Sandbox Code Playgroud)
请注意,这些日期字符串不一定是标准日历上的有效日期(因此与POSIXt类不兼容Date)。使用日历,日期1600-02-30有效,而1600-03-31无效360_day。
这适用于任何 CF 日历,包括标准日历。这比使用 PCICt 包的示例中的两行代码要简单得多。
CF 约定中有九种不同的日历,其中一些与 POSIXt 不兼容:365_day并且noleap没有任何闰日,即使在 2016 年或 2020 年这样的年份也没有;在366_day日历中all_leap每年都有闰日;最后,在360_day日历中,每年有 12 个月,每月 30 天。
对于您的日期,您不会遇到问题,因为它总是在月中的某一天(另一个 CF 约定),但是对于每日数据,您很快就会遇到问题。as.character.PCICt()接下来as.Date()将为您提供预期的 s 向量Date,但它会缺少天数(例如,没有 1 月 31 日)以及NA2 月 29 日和 30 日的值。
同样,CFtime 包将与这些日历一起使用,而不会丢失任何数据。
在全球气候研究中,人们的兴趣通常是确定相对于某个基线的变化。大多数研究都使用 1850 年作为基准年,自那一年以来,目前全球变暖了约 1.3K。鉴于全球平均气温约为 287K,我们在大约 170 年来观察到的相对变化为1.3 / 287 = 0.45%。许多研究使用更小的比较周期,例如“21 世纪中叶的气温与 1991-2020 年基准期相比”。随意移动一两天(就像 PCICt 所做的那样)可能会导致数据中的信号变得模糊。