从频率 = 23 的不规则 (as.Date) 时间序列创建规则时间序列

发布于 2024-10-15 00:15:31 字数 2042 浏览 1 评论 0原文

我在 R 中遇到以下问题。我想从不规则时间序列(即日期和数据值列表)创建一个 ts() 对象(即规则时间序列)。

您可以使用以下数据集和 R 脚本重现该问题:

# dput(dd) result    
dd <- structure(list(NDVI = structure(c(14L, 4L, 11L, 12L, 20L, 17L, 
    5L, 7L, 21L, 23L, 25L, 19L, 15L, 9L, 3L, 24L, 2L, 6L, 22L, 16L, 
    13L, 18L, 10L, 8L, 1L), .Names = c("1", "2", "3", "4", "5", "6", 
    "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", 
    "18", "19", "20", "21", "22", "23", "24", "25"), .Label = c("0.4186", 
    "0.5452", "0.5915", "0.5956", "0.6010", "0.6860", "0.6966", "0.7159", 
    "0.7161", "0.7264", "0.7281", "0.7523", "0.7542", "0.7701", "0.7751", 
    "0.7810", "0.7933", "0.8075", "0.8113", "0.8148", "0.8207", "0.8302", 
    "0.8305", "0.8369", "0.9877"), class = "factor"), DATUM = structure(c(11005, 
    11021, 11037, 11085, 11101, 11117, 11133, 11149, 11165, 11181, 
    11197, 11213, 11229, 11245, 11261, 11277, 11293, 11309, 11323, 
    11339, 11355, 11371, 11387, 11403, 11419), class = "Date")), .Names = c("NDVI", 
    "DATUM"), row.names = c("1", "2", "3", "4", "5", "6", "7", "8", 
    "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", 
    "20", "21", "22", "23", "24", "25"), class = "data.frame")

require(zoo)
dd$DATUM <- as.Date(dd$DATUM,"A%Y%j") # Ayear,julianday
z <- zoo(dd$NDVI,dd$DATUM,frequency=23)
z  # this is a regular time series with a frequency=23 and start=c(2000,1)
# there are 5 measurements in 2000 (2 jan, 1 feb, 2 apr) for which no data is available 
# this should be marked as an NA is the final regular time series
ts.z <- as.ts(z,start=c(2000,1),frequency=23)

但这不起作用,因为我获得了包含每日时间步长的非常长的常规时间序列。 我想获得一个频率 = 23 的 ts 对象,正确指示数据不可用的位置 NA。

我一直在根据此处列出的年度数据示例尝试一切 将不规则时间序列转换为规则时间序列

但它不适用于频率为 23 的数据(即每年 23 个值)。我想我可以通过避免设置 dd$DATUM as.Date() 来解决这个问题,而是作为一个动物园对象,可以作为每年 23 个值的时间序列进行排序。

有什么想法吗?

感谢您的帮助

I have the following problem in R. I would like to create a ts() object (i.e. a regular time series) from a irregular time series (i.e. a list of dates and data values).

You can reproduce the problem with the following data set and R script:

# dput(dd) result    
dd <- structure(list(NDVI = structure(c(14L, 4L, 11L, 12L, 20L, 17L, 
    5L, 7L, 21L, 23L, 25L, 19L, 15L, 9L, 3L, 24L, 2L, 6L, 22L, 16L, 
    13L, 18L, 10L, 8L, 1L), .Names = c("1", "2", "3", "4", "5", "6", 
    "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", 
    "18", "19", "20", "21", "22", "23", "24", "25"), .Label = c("0.4186", 
    "0.5452", "0.5915", "0.5956", "0.6010", "0.6860", "0.6966", "0.7159", 
    "0.7161", "0.7264", "0.7281", "0.7523", "0.7542", "0.7701", "0.7751", 
    "0.7810", "0.7933", "0.8075", "0.8113", "0.8148", "0.8207", "0.8302", 
    "0.8305", "0.8369", "0.9877"), class = "factor"), DATUM = structure(c(11005, 
    11021, 11037, 11085, 11101, 11117, 11133, 11149, 11165, 11181, 
    11197, 11213, 11229, 11245, 11261, 11277, 11293, 11309, 11323, 
    11339, 11355, 11371, 11387, 11403, 11419), class = "Date")), .Names = c("NDVI", 
    "DATUM"), row.names = c("1", "2", "3", "4", "5", "6", "7", "8", 
    "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", 
    "20", "21", "22", "23", "24", "25"), class = "data.frame")

require(zoo)
dd$DATUM <- as.Date(dd$DATUM,"A%Y%j") # Ayear,julianday
z <- zoo(dd$NDVI,dd$DATUM,frequency=23)
z  # this is a regular time series with a frequency=23 and start=c(2000,1)
# there are 5 measurements in 2000 (2 jan, 1 feb, 2 apr) for which no data is available 
# this should be marked as an NA is the final regular time series
ts.z <- as.ts(z,start=c(2000,1),frequency=23)

But this does not work, as I obtain a very long regular time series containing daily time steps.
I would like to obtain a ts object with a frequency=23 correctly indicating the position for which data is not available as NA.

I have been trying everything based on the example listed here for yearly data
Convert a irregular time series to a regular time series

but it does not work for data with a frequency of 23 (i.e. 23 values a year). I think I could solve it by avoiding to set dd$DATUM as.Date() but as an zoo object that can be ordered as a time series with 23 values a year.

Any ideas?

Thanks for your help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

影子是时光的心 2024-10-22 00:15:31

23 不能平均划分为一年中的天数,因此您必须合成自己的时间尺度,以便将每年分为 23 个相等的部分。将 dd (具有“日期”类时间的版本)转换为zoo,并根据由年份加上分数组成的新比例创建一个新系列。最后将其转换为 ts 系列:

library(zoo)
z <- zoo(as.numeric(as.character(dd[[1]])), dd[[2]]) 
lt <- unclass(as.POSIXlt(time(z)))
yr <- lt$year + 1900
jul <- lt$yday
delta <- min(unlist(tapply(jul, yr, diff))) # 16
zz <- aggregate(z, yr + jul / delta / 23)

as.ts(zz)

给出:

Time Series:
Start = c(2000, 4) 
End = c(2001, 7) 
Frequency = 23 
 [1] 0.7701 0.5956 0.7281     NA     NA 0.7523 0.8148 0.7933 0.6010 0.6966
[11] 0.8207 0.8305 0.9877 0.8113 0.7751 0.7161 0.5915 0.8369 0.5452 0.6860
[21] 0.8302 0.7810 0.7542 0.8075 0.7264 0.7159 0.4186

23 does not evenly divide into the number of days in a year so you will have to synthesize your own time scale such that each year is divided into 23 equal pieces. Convert dd (the version that has "Date" class times) to zoo and create a new series based on a new scale made up of the year plus a fraction. Finally convert that to a ts series:

library(zoo)
z <- zoo(as.numeric(as.character(dd[[1]])), dd[[2]]) 
lt <- unclass(as.POSIXlt(time(z)))
yr <- lt$year + 1900
jul <- lt$yday
delta <- min(unlist(tapply(jul, yr, diff))) # 16
zz <- aggregate(z, yr + jul / delta / 23)

as.ts(zz)

giving:

Time Series:
Start = c(2000, 4) 
End = c(2001, 7) 
Frequency = 23 
 [1] 0.7701 0.5956 0.7281     NA     NA 0.7523 0.8148 0.7933 0.6010 0.6966
[11] 0.8207 0.8305 0.9877 0.8113 0.7751 0.7161 0.5915 0.8369 0.5452 0.6860
[21] 0.8302 0.7810 0.7542 0.8075 0.7264 0.7159 0.4186
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文