如何使循环中的日期结果相关?

huangapple go评论93阅读模式
英文:

How to make the result of dates in the loop correlative?

问题

I made a code to calculate daily data from MODIS 8-day data, as it is known the last data of the year is always divided by 5 or 6 and not by 8 depending on whether it is a leap year or not so I added it, the problem is the result because I have repeated dates and other missing ones, for example September 20 is repeated twice but I don't have 21. How could I solve this?

So that the code is well understood, the first thing I did was change the crs of my rasters one by one because I had errors applying it directly to the stack at the end, this worked fine, and then with that list with my reprojected rasters I worked with the loop I have doubts

Here is my code

  1. library(raster)
  2. library(terra)
  3. library(lubridate)
  4. archivos_ET <- list.files(path = "/", pattern = "ET_\\d{4}_\\d{3}", full.names = TRUE)
  5. # Save all raster et files in a list called et_proy
  6. # Create a list to store the daily rasters
  7. et_dia <- list()
  8. for (i in 1:length(et_proy)) {
  9. # Load the raster
  10. raster_actual <- et_proy[[i]]
  11. # Get the year and day of the current file name
  12. partes_nombre <- strsplit(basename(archivos_ET[i]), "_")[[1]]
  13. ano <- as.integer(partes_nombre[2])
  14. dia <- as.integer(gsub(".tif", "", partes_nombre[3]))
  15. # Check if the year is a leap year
  16. es_bisiesto <- ifelse(ano %% 4 == 0 & (ano %% 100 != 0 | ano %% 400 == 0), TRUE, FALSE)
  17. # Determine the divisor according to whether it is a leap year and the day is 361 (it is the last day of the modis products in a year)
  18. divisor <- ifelse(dia == 361, ifelse(es_bisiesto, 6, 5), 8)
  19. # Loop to split the current raster into daily rasters and store them
  20. for (j in 1:(divisor-1)) {
  21. # Calculate the date of the daily raster
  22. fecha <- as.Date(paste(ano, "-01-01", sep = "")) + dia + j - 1
  23. # Calculate the daily raster
  24. raster_diario <- raster_actual / divisor
  25. # Assign date to daily raster
  26. names(raster_diario) <- format(fecha, "%Y-%m-%d")
  27. # Add the daily raster to the list
  28. et_dia[[length(et_dia) + 1]] <- raster_diario
  29. }
  30. # Calculate the date of the last raster
  31. fecha_ultimo <- as.Date(paste(ano, "-01-01", sep = "")) + dia + divisor - 2
  32. # Calculate the last raster
  33. raster_ultimo <- raster_actual / divisor
  34. # Assign date to last raster
  35. names(raster_ultimo) <- format(fecha_ultimo, "%Y-%m-%d")
  36. # Add the last raster to the list
  37. et_dia[[length(et_dia) + 1]] <- raster_ultimo
  38. }

And here is an example of my result

  1. [[993]]
  2. class : RasterLayer
  3. dimensions : 33, 56, 1848 (nrow, ncol, ncell)
  4. resolution : 346, 463 (x, y)
  5. extent : 602219.9, 621595.9, 5353158, 5368437 (xmin, xmax, ymin, ymax)
  6. crs : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs
  7. source : memory
  8. names : X2016.09.20
  9. values : 0.6063787, 2.016294 (min, max)
  10. [[994]]
  11. class : RasterLayer
  12. dimensions : 33, 56, 1848 (nrow, ncol, ncell)
  13. resolution : 346, 463 (x, y)
  14. extent : 602219.9, 621595.9, 5353158, 5368437 (xmin, xmax, ymin, ymax)
  15. crs : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs
  16. source : memory
  17. names : X2016.09.20
  18. values : 0.6063787, 2.016294 (min, max)
  19. [[995]]
  20. class : RasterLayer
  21. dimensions : 33, 56, 1848 (nrow, ncol, ncell)
  22. resolution : 346, 463 (x, y)
  23. extent : 602219.9, 621595.9, 5353158, 5368437 (xmin, xmax, ymin, ymax)
  24. crs : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs
  25. source : memory
  26. names : X2016.09.22
  27. values : 1.3125, 2.177313 (min, max)
  28. [[996]]
  29. class : RasterLayer
  30. dimensions : 33, 56, 1848 (nrow, ncol, ncell)
  31. resolution : 346, 463 (x, y)
  32. extent : 602219.9, 621595.9, 5353158, 5368437 (xmin, xmax, ymin, ymax)
  33. crs : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs
  34. source : memory
  35. names : X2016.09.23
  36. values : 1.3125, 2.177313 (min, max)

I also realized that the first data of my series of years, that is, 2014-01-01, is not there either.

英文:

I made a code to calculate daily data from MODIS 8-day data, as it is known the last data of the year is always divided by 5 or 6 and not by 8 depending on whether it is a leap year or not so I added it, the problem is the result because I have repeated dates and other missing ones, for example September 20 is repeated twice but I don't have 21. How could I solve this?

So that the code is well understood, the first thing I did was change the crs of my rasters one by one because I had errors applying it directly to the stack at the end, this worked fine, and then with that list with my reprojected rasters I worked with the loop I have doubts

Here is my code

  1. library(raster)
  2. library(terra)
  3. library(lubridate)
  4. archivos_ET &lt;- list.files(path = &quot;/&quot;, pattern = &quot;ET_\\d{4}_\\d{3}&quot;, full.names = TRUE)
  5. #Save all raster et files in a list called et_proy
  6. # Create a list to store the daily rasters
  7. et_dia &lt;- list()
  8. for (i in 1:length(et_proy)) {
  9. # # Load the raster
  10. raster_actual &lt;- et_proy[[i]]
  11. # Get the year and day of the current file name
  12. partes_nombre &lt;- strsplit(basename(archivos_ET[i]), &quot;_&quot;)[[1]]
  13. ano &lt;- as.integer(partes_nombre[2])
  14. dia &lt;- as.integer(gsub(&quot;.tif&quot;, &quot;&quot;, partes_nombre[3]))
  15. # Check if the year is a leap year
  16. es_bisiesto &lt;- ifelse(ano %% 4 == 0 &amp; (ano %% 100 != 0 | ano %% 400 == 0), TRUE, FALSE)
  17. # Determine the divisor according to whether it is a leap year and the day is 361 (it is the last day of the modis products in a year)
  18. divisor &lt;- ifelse(dia == 361, ifelse(es_bisiesto, 6, 5), 8)
  19. # Loop to split the current raster into daily rasters and store them
  20. for (j in 1:(divisor-1)) {
  21. # Calcular la fecha del raster diario
  22. fecha &lt;- as.Date(paste(ano, &quot;-01-01&quot;, sep = &quot;&quot;)) + dia + j - 1
  23. # Calculate date from daily raster
  24. raster_diario &lt;- raster_actual / divisor
  25. # Assign date to daily raster
  26. names(raster_diario) &lt;- format(fecha, &quot;%Y-%m-%d&quot;)
  27. # Add the daily raster to the list
  28. et_dia[[length(et_dia) + 1]] &lt;- raster_diario
  29. }
  30. # Calculate the date of the last raster
  31. fecha_ultimo &lt;- as.Date(paste(ano, &quot;-01-01&quot;, sep = &quot;&quot;)) + dia + divisor - 2
  32. # Calculate the last raster
  33. raster_ultimo &lt;- raster_actual / divisor
  34. # Assign date to last raster
  35. names(raster_ultimo) &lt;- format(fecha_ultimo, &quot;%Y-%m-%d&quot;)
  36. # Add the last raster to the list
  37. et_dia[[length(et_dia) + 1]] &lt;- raster_ultimo
  38. }

And here is an example of my result

  1. [[993]]
  2. class : RasterLayer
  3. dimensions : 33, 56, 1848 (nrow, ncol, ncell)
  4. resolution : 346, 463 (x, y)
  5. extent : 602219.9, 621595.9, 5353158, 5368437 (xmin, xmax, ymin, ymax)
  6. crs : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs
  7. source : memory
  8. names : X2016.09.20
  9. values : 0.6063787, 2.016294 (min, max)
  10. [[994]]
  11. class : RasterLayer
  12. dimensions : 33, 56, 1848 (nrow, ncol, ncell)
  13. resolution : 346, 463 (x, y)
  14. extent : 602219.9, 621595.9, 5353158, 5368437 (xmin, xmax, ymin, ymax)
  15. crs : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs
  16. source : memory
  17. names : X2016.09.20
  18. values : 0.6063787, 2.016294 (min, max)
  19. [[995]]
  20. class : RasterLayer
  21. dimensions : 33, 56, 1848 (nrow, ncol, ncell)
  22. resolution : 346, 463 (x, y)
  23. extent : 602219.9, 621595.9, 5353158, 5368437 (xmin, xmax, ymin, ymax)
  24. crs : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs
  25. source : memory
  26. names : X2016.09.22
  27. values : 1.3125, 2.177313 (min, max)
  28. [[996]]
  29. class : RasterLayer
  30. dimensions : 33, 56, 1848 (nrow, ncol, ncell)
  31. resolution : 346, 463 (x, y)
  32. extent : 602219.9, 621595.9, 5353158, 5368437 (xmin, xmax, ymin, ymax)
  33. crs : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs
  34. source : memory
  35. names : X2016.09.23
  36. values : 1.3125, 2.177313 (min, max)

I also realized that the first data of my series of years, that is, 2014-01-01, is not there either.

答案1

得分: 1

以下是翻译好的部分:

这是一个通用解决方案。

8天时间步骤的示例数据

  1. library(terra)
  2. r <- rast(system.file("ex/logo.tif", package="terra"))
  3. s <- c(r/c(1:3), r/c(4:6))
  4. time(s) <- as.Date("2001-01-03") + seq(0, 40, 8)
  5. time(s)
  6. #[1] "2001-01-03" "2001-01-11" "2001-01-19" "2001-01-27" "2001-02-04" "2001-02-12"

添加一个层以使最小时间步长为一天

  1. x <- s[[1]]
  2. time(x) <- time(x)-1
  3. x <- c(x, s)

现在使用fillTime在8天间隔之间添加(空)层,并删除添加的层。

  1. sx <- fillTime(x)[[-1]]
  2. time(sx)
  3. # [1] "2001-01-03" "2001-01-04" "2001-01-05" "2001-01-06" "2001-01-07" "2001-01-08" "2001-01-09" "2001-01-10" "2001-01-11" "2001-01-12" "2001-01-13"
  4. #[12] "2001-01-14" "2001-01-15" "2001-01-16" "2001-01-17" "2001-01-18" "2001-01-19" "2001-01-20" "2001-01-21" "2001-01-22" "2001-01-23" "2001-01-24"
  5. #[23] "2001-01-25" "2001-01-26" "2001-01-27" "2001-01-28" "2001-01-29" "2001-01-30" "2001-01-31" "2001-02-01" "2001-02-02" "2001-02-03" "2001-02-04"
  6. #[34] "2001-02-05" "2001-02-06" "2001-02-07" "2001-02-08" "2001-02-09" "2001-02-10" "2001-02-11" "2001-02-12" "2001-02-13" "2001-02-14" "2001-02-15"
  7. #[45] "2001-02-16" "2001-02-17" "2001-02-18" "2001-02-19" "2001-02-20" "2001-02-21" "2001-02-22" "2001-02-23" "2001-02-24" "2001-02-25" "2001-02-26"
  8. #[56] "2001-02-27" "2001-02-28" "2001-03-01" "2001-03-02" "2001-03-03" "2001-03-04" "2001-03-05" "2001-03-06" "2001-03-07" "2001-03-08"

使用approximate进行线性插值估算缺失值。

  1. a <- approximate(sx)
  1. plot(time(a), minmax(a)[2,])

如何使循环中的日期结果相关?

更“手动”的方法:

  1. stm <- time(s)
  2. tms <- seq(stm[1], stm[length(stm)], 1)
  3. r <- rast(s, nlyr=length(tms))
  4. time(r) <- tms
  5. i <- match(stm, tms)
  6. r[[i]] <- s

然后继续处理。

英文:

Here is a general solution.

Example data at 8-day time step

  1. library(terra)
  2. r &lt;- rast(system.file(&quot;ex/logo.tif&quot;, package=&quot;terra&quot;))
  3. s &lt;- c(r/c(1:3), r/c(4:6))
  4. time(s) &lt;- as.Date(&quot;2001-01-03&quot;) + seq(0, 40, 8)
  5. time(s)
  6. #[1] &quot;2001-01-03&quot; &quot;2001-01-11&quot; &quot;2001-01-19&quot; &quot;2001-01-27&quot; &quot;2001-02-04&quot; &quot;2001-02-12&quot;

Add one layer to make the smallest time-step one day

  1. x &lt;- s[[1]]
  2. time(x) &lt;- time(x)-1
  3. x &lt;- c(x, s)

Now use fillTime to add (empty) layers inbetween the 8 days intervals, and remove the added layer.

  1. sx &lt;- fillTime(x)[[-1]]
  2. time(sx)
  3. # [1] &quot;2001-01-03&quot; &quot;2001-01-04&quot; &quot;2001-01-05&quot; &quot;2001-01-06&quot; &quot;2001-01-07&quot; &quot;2001-01-08&quot; &quot;2001-01-09&quot; &quot;2001-01-10&quot; &quot;2001-01-11&quot; &quot;2001-01-12&quot; &quot;2001-01-13&quot;
  4. #[12] &quot;2001-01-14&quot; &quot;2001-01-15&quot; &quot;2001-01-16&quot; &quot;2001-01-17&quot; &quot;2001-01-18&quot; &quot;2001-01-19&quot; &quot;2001-01-20&quot; &quot;2001-01-21&quot; &quot;2001-01-22&quot; &quot;2001-01-23&quot; &quot;2001-01-24&quot;
  5. #[23] &quot;2001-01-25&quot; &quot;2001-01-26&quot; &quot;2001-01-27&quot; &quot;2001-01-28&quot; &quot;2001-01-29&quot; &quot;2001-01-30&quot; &quot;2001-01-31&quot; &quot;2001-02-01&quot; &quot;2001-02-02&quot; &quot;2001-02-03&quot; &quot;2001-02-04&quot;
  6. #[34] &quot;2001-02-05&quot; &quot;2001-02-06&quot; &quot;2001-02-07&quot; &quot;2001-02-08&quot; &quot;2001-02-09&quot; &quot;2001-02-10&quot; &quot;2001-02-11&quot; &quot;2001-02-12&quot; &quot;2001-02-13&quot; &quot;2001-02-14&quot; &quot;2001-02-15&quot;
  7. #[45] &quot;2001-02-16&quot; &quot;2001-02-17&quot; &quot;2001-02-18&quot; &quot;2001-02-19&quot; &quot;2001-02-20&quot; &quot;2001-02-21&quot; &quot;2001-02-22&quot; &quot;2001-02-23&quot; &quot;2001-02-24&quot; &quot;2001-02-25&quot; &quot;2001-02-26&quot;
  8. #[56] &quot;2001-02-27&quot; &quot;2001-02-28&quot; &quot;2001-03-01&quot; &quot;2001-03-02&quot; &quot;2001-03-03&quot; &quot;2001-03-04&quot; &quot;2001-03-05&quot; &quot;2001-03-06&quot; &quot;2001-03-07&quot; &quot;2001-03-08&quot;

Use approximate to estimate missing values by linear interpolation.

  1. a &lt;- approximate(sx)
  1. plot(time(a), minmax(a)[2,])

如何使循环中的日期结果相关?

A more "manual" approach:

  1. stm &lt;- time(s)
  2. tms &lt;- seq(stm[1], stm[length(stm)], 1)
  3. r &lt;- rast(s, nlyr=length(tms))
  4. time(r) &lt;- tms
  5. i &lt;- match(stm, tms)
  6. r[[i]] &lt;- s

And take it from there.

答案2

得分: 0

我认为我已经解决了我的问题,解决方法是创建了一个初始日期并检查了名称的分配位置。

  1. et_dia <- list()
  2. fecha_actual <- as.Date("2013-12-31")
  3. for (i in 1:length(et_proy)) {
  4. raster_actual <- et_proy[[i]]
  5. partes_nombre <- strsplit(basename(archivos_ET[i]), "_")[[1]]
  6. ano <- as.integer(partes_nombre[2])
  7. dia <- as.integer(substr(partes_nombre[3], 1, 3))
  8. es_bisiesto <- ifelse(ano %% 4 == 0 & (ano %% 100 != 0 | ano %% 400 == 0), TRUE, FALSE)
  9. divisor <- ifelse(dia == 361, ifelse(es_bisiesto, 6, 5), 8)
  10. for (j in 1:(divisor)) {
  11. fecha_actual <- fecha_actual + 1
  12. raster_diario <- raster_actual / divisor
  13. names(raster_diario) <- format(fecha_actual, "%Y-%m-%d")
  14. et_dia[[length(et_dia) + 1]] <- raster_diario
  15. }
  16. }
英文:

I think I have solved my question, the solution was to have created an initial date and to have reviewed where the name was assigned.

  1. et_dia &lt;- list()
  2. fecha_actual &lt;- as.Date(&quot;2013-12-31&quot;)
  3. for (i in 1:length(et_proy)) {
  4. raster_actual &lt;- et_proy[[i]]
  5. partes_nombre &lt;- strsplit(basename(archivos_ET[i]), &quot;_&quot;)[[1]]
  6. ano &lt;- as.integer(partes_nombre[2])
  7. dia &lt;- as.integer(substr(partes_nombre[3], 1, 3))
  8. es_bisiesto &lt;- ifelse(ano %% 4 == 0 &amp; (ano %% 100 != 0 | ano %% 400 == 0), TRUE, FALSE)
  9. divisor &lt;- ifelse(dia == 361, ifelse(es_bisiesto, 6, 5), 8)
  10. for (j in 1:(divisor)) {
  11. fecha_actual &lt;- fecha_actual + 1
  12. raster_diario &lt;- raster_actual / divisor
  13. names(raster_diario) &lt;- format(fecha_actual, &quot;%Y-%m-%d&quot;)
  14. et_dia[[length(et_dia) + 1]] &lt;- raster_diario
  15. }
  16. }

huangapple
  • 本文由 发表于 2023年5月15日 01:20:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76248793.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定