1
$\begingroup$

I'm trying to effectively increase the temporal resolution of a daily time series data to 6-hourly time series (modeled weather data). I've been using na.spline from the zoo. Here is how I've been doing this:

library(zoo)
temp = c(260.9394, 264.3018, 270.2295,269.3193, 270.9833, 271.4790, 269.2528 ,271.5263, 271.0616, 263.4052, 260.7776 ,262.1539, 260.4698 ,259.6320 ,266.3442, 261.2173 ,253.5278, 252.5940 ,255.2761,253.0223, 255.4660, 258.4136, 268.4329 ,269.1272, 268.3249, 267.6087, 269.4851, 270.2795 ,266.0357 ,260.9807, 263.3990, 266.6847 ,266.0555, 268.3860 ,270.5075 ,270.7101, 266.2647, 263.1466, 261.3249, 264.5570 ,262.4109, 267.3654 ,268.7764, 269.1429 ,275.2494 ,276.8388, 276.0056, 282.2490 ,279.3987, 266.1445 ,263.2737,257.9539, 254.9523, 260.2066, 264.2155, 270.5643, 269.1971, 267.3094, 260.6333, 260.4092, 263.7590,267.1073, 269.1791, 268.7179, 268.1320, 258.5653, 256.9442, 260.8293,267.6224, 270.4454, 270.9205, 272.4834, 276.7073, 272.9083, 281.7278, 280.7053, 286.0500, 284.9832, 271.0922, 270.2727, 272.9502, 279.6241, 279.6601, 278.8676, 276.0311,278.0432, 276.0992, 273.0579, 275.3508, 276.2788, 274.1192, 274.7629, 276.9832, 280.6208, 270.1893, 265.8163, 268.5312, 273.1192, 271.2437, 273.2898, 274.9559, 271.3247,274.0296, 274.3720, 268.9793, 274.1874, 276.5400, 277.8003,272.9678,272.7812, 271.1283, 276.2137, 278.8361, 283.7280, 280.6618, 277.1862, 275.4617, 273.6890, 275.6335,275.7692, 278.0294,278.6085, 278.1408 ,278.5306 ,276.4064, 277.5828, 282.4601 ,286.0646, 285.5323 ,283.9420 ,280.9373, 283.5115 ,285.5747, 285.3726 ,284.7168, 283.4072,283.6460, 285.8925 ,287.7186 ,285.3997, 289.1151,289.2271, 293.4171, 289.7754 ,290.3863, 289.6272, 291.9551, 293.8194, 285.5756, 284.0607, 287.2251 ,290.9961 ,288.9530,288.9829, 289.4866, 293.2368 ,287.5108, 294.7983 ,296.1631,294.4269, 292.5922 ,286.9019, 282.8738, 283.4177, 285.9086, 285.5735, 286.2843 ,288.2936, 289.9575 ,287.3752,287.7389, 287.6944, 288.7362, 291.3151 ,292.0483, 295.6626 ,295.1491, 294.6186 ,295.1886, 295.6821, 294.5723, 295.5624, 296.3948, 297.0867, 294.7425, 293.2665, 295.3842,297.3065, 297.6444, 297.3771, 294.2589, 293.1402,297.9673, 303.8832, 300.2515, 294.8088, 292.9465, 294.5560, 293.5795, 291.2845, 292.0042, 292.8047, 292.5544, 291.4802,291.2924, 296.4316, 290.7670, 292.6044, 295.0291, 297.4236, 297.8194, 298.4617, 294.3469,290.6657, 291.5336, 296.0067, 295.8909, 294.7652, 295.9294, 297.0009 ,297.5438,297.5055, 299.8651, 296.5216 ,295.9416, 294.6706, 292.8246 ,295.4045, 291.9977 ,291.4641, 291.8502 ,292.5085, 292.4158, 294.8775, 292.9365, 294.1278, 294.0945, 292.2523,293.9971, 299.8319, 296.3214, 292.7899, 289.1313, 289.3746, 290.2141, 292.0596, 295.5131, 295.3895, 294.5305, 290.8510, 288.0043, 291.1497, 293.4218,291.4864,294.8860,296.5399,284.8989,286.2889,286.7507,283.6707,285.038,288.5444,290.2072,289.3766,288.4058,289.9024,287.7706,282.0836,279.6411,280.878,283.8073, 287.0587,282.0472, 279.3339, 278.4666, 279.7615, 277.9067, 277.3667, 277.5933,276.9392,277.3469,276.4537,277.2365,279.1784,281.6197,284.2389,283.7059 ,283.4021, 281.3361,280.0453, 281.8986 ,281.1670, 282.5850, 286.6981 ,281.8985 ,277.7366, 275.4608, 278.4460 ,282.3974, 282.1050, 279.2068, 278.6987, 274.1590, 268.1413 ,270.9254, 277.8294,283.1120 ,281.8789, 285.1766, 284.1758, 283.2682 ,276.6518, 270.9003,269.9474, 272.6488 ,272.3387, 273.6503, 276.1812, 276.1082, 277.7733, 279.2593, 280.6460, 278.0175,278.0469 ,278.6865, 275.7430, 273.8073, 276.0212, 275.1905, 272.0544, 262.0764, 261.9173, 260.7959, 265.9595, 262.9587, 259.9734, 258.0081, 256.6400, 253.1440, 253.5497,256.5918, 259.1784,263.0086,265.8650 ,263.2765 ,257.5844 ,259.9606 ,262.6104, 263.2550, 268.3223, 268.7100, 266.7353, 264.8430, 262.4933, 259.9666 ,262.5295 ,260.8611,256.8401 ,259.5594, 264.9890, 264.5033 ,268.2536 ,271.1512, 268.5712 ,267.4058)

temp = data.frame(temp)
six_hour = data.frame()

#Place 3 NAs in between each daily value from temp
for (x in seq(from=0, to=1460, by=4)){
   six_hour[x,1] = temp[x/4,1]}

spline.met = list()
spline.met = na.spline(six_hour)
spline.met = data.frame(spline.met)

I'm working with modeled data above. While this is a quick and dirty way, it doesn't have the same variability or random deviation that observed data will show. For example, if I look at a real dataset complete with observed 6 hourly values from the same location, it will show much greater variability. For this, I will average my observed dataset for each day, then go through the code above to show the differences between actual 6 hour data and spline interpolated data. (I can only show half of a year though due to R list limits)

obs = c(0,53,70,0,0,40,38,0,0,28,27,0,0,16,23,0,0,28,30,0,0,36,27,0,0,15,32,0,0,55,38,0,0,62,143,0,0,200,190,0,0,134,176,0,0,129,131,0,0,39,109,0,0,162,138,0,0,131,137,0,0,26,31,0,0,31,43,0,0,123,211,0,0,39,29,0,0,45,94,0,0,214,196,0,0,42,28,0,0,228,167,0,0,66,85,0,0,194,235,0,0,206,231,0,0,203,227,0,0,169,84,0,0,28,49,0,0,83,79,0,0,150,129,0,0,42,49,0,0,128,236,0,0,23,42,0,0,74,124,0,0,129,230,0,0,256,292,0,0,219,263,0,0,176,291,0,0,175,207,0,0,59,50,0,0,149,120,0,0,112,179,0,0,140,298,0,0,107,130,0,0,315,267,0,0,83,75,0,0,281,331,0,0,322,352,0,0,328,352,0,0,332,327,0,0,311,305,0,0,147,272,0,0,234,348,0,0,104,90,0,0,344,373,0,0,300,223,0,0,234,383,0,0,271,349,0,0,208,221,0,0,220,314,0,0,125,279,0,0,386,397,0,0,160,119,0,0,185,122,0,0,142,261,0,0,90,129,0,0,287,336,0,0,357,357,0,0,353,245,0,0,376,209,0,0,42,135,0,0,166,219,0,0,412,420,0,0,392,413,0,0,444,474,0,0,460,479,0,0,470,478,0,0,457,461,0,0,441,476,0,0,463,401,0,0,228,175,0,0,240,246,0,0,246,287,0,0,491,506,0,0,491,482,0,0,493,495,0,0,484,490,0,0,184,111,0,0,106,180,0,0,131,426,0,0,66,63,0,0,491,537,1,1,544,539,1,2,534,323,0,0,232,300,0,2,420,562,2,2,560,523,2,2,483,352,1,0,397,507,2,2,482,272,0,0,446,453,3,5,337,163,3,4,543,498,3,4,550,505,2,2,493,558,2,5,590,571,4,4,584,562,3,2,288,283,4,7,204,326,9,0,187,301,1,5,236,220,5,2,186,505,6,7,353,171,1,11,637,614,7,10,622,581,8,10,621,590,7,11,584,390,2,3,251,191,1,0,78,40,0,0,52,63,1,3,160,315,5,4,565,618,9,16,430,328,3,5,225,312,8,16,393,502,4,16,623,255,10,17,159,85,4,1,97,200,2,10,300,448,10,3,98,104,1,4,160,94,5,2,127,182,7,6,381,187,2,6,174,185,9,13,247,467,16,6,541,580,11,7,422,617,11,10,535,646,16,24,412,340,19,26,708,569,18,26,681,652,19,30,656,626,13,16,353,406,3,5,240,338,23,19,535,436,17,17,531,371,5,13,580,621,17,24,638,577,7,0,465,479,9,25,604,593,21,16,532,489,17,28,669,611,22,28,690,530,21,30,692,656,22,26,654,449,11,10,154,321,11,27,652,648,21,30,691,672,21,26,578,278,9,32,687,669,22,21,668,568,19,32,669,560,20,10,446,342,17,25,629,622,25,18,530,464,15,16,599,526,11,23,560,512,11,9,516,597,26,30,340,529,26,31,504,211,7,14,585,559,19,28,524,661,28,30,672,644,18,4,355,363,14,3,343,620,33,29,673,635,20,4,504,419,16,17,264,615,26,22,635,584,23,18,595,580,14,3,384,458,26,23,655)

obs = data.frame(obs)
reso = floor(365/2)
step = 4
daily.obs = data.frame()
for (x in 1:reso){
  daily.obs[x,1] <- mean(obs[(x*step-step+1):(x*step),1])}
tem.obs = data.frame()
for (x in seq(from=0, to=732, by=4)){
  tem.obs[x,1] = daily.obs[x/4,1]}

spline.obs = list()
spline.obs = na.spline(tem.obs[1])
spline.obs = data.frame(spline.obs[1:730])

Now if we plot up the comparison between observed and spline interpolated..

plot(obs$obs,type = 'l', col = "blue")
lines(spline.obs, col = "red")
legend("topleft", legend =  c("Spline Interpolation","Observations"), cex     =0.8, col=c("red","blue"), lty=1:1)

We can clearly see some differences. Is there any way to alter the spline function to increase it's variability/deviation to capture more of the randomness associated with real data? Is there another package I could be using to tackle this problem?

Note: I do not have access to the original modeling code and cannot increase the resolution of the actual model. I must downscale the product of the model.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.