Hello everyone, hope you can help me trying to avoid DRY in my code.
I am trying to evaluate the sea temperature. I have results with this
first code, but I want to improve with a loop function, just I don't know how to convert to "for function".
CODE
#open image
library(oce)
library(ncdf4)
fn <- "C:/images/gertmo/figure_sun1.nc"
vart <- nc_open(fn)
ray1 <- ncvar_get(vart,"degrees")
nc_close(vart)
final1 <- ray1[c(ocean)] #Here "ocean" was defined in other object before but is a constant in all files"
fn <- "C:/images/gertmo/figure_sun2.nc"
vart <- nc_open(fn)
ray2 <- ncvar_get(vart,"degrees")
nc_close(vart)
final2 <- ray2[c(ocean)]
..
The following for 30 days.
#then using "cbind", to get a file with all the variables "final"
SUN2015 <- cbind(final,final2,...)
The files are in the same folder, and in numerically order.
I can't test this without your files, but I think this should work. You use map_dfc to iterate a function over a sequence of integers from 1 to 30, using sprintf to create the string for the filename from the integer at each step. map_dfc specifies that you want the results of the iterating to be bound by column into a new data frame.
Hello ulfelder, Thanks for your soon reply.
I'm trying to run your code, I wrote these lines:
loop_list <- map_dfc(seq(27),function(i){
i=3:29
require(oce)
require(ncdf4)
filename <- sprintf("C:/images/february/modis2019/A2019033.L3m_DAY_CHL.x_chlor_a%s.nc",x)
vart <- nc_open(filename)
ray <- ncvar_get(vart,"degrees")
nc_close(vart)
final <- ray[c(ocean)]
return(final)
})
ocean2019 <- do.call(cbind, loop_list)
Getting the error:
Error in sprintf("C:/images/february/modis2019/A2019033.L3m_DAY_CHL.x_chlor_a%s.nc", :
object 'x' not find
There some points that I had to explain before:
In the folder exist 29 files numerically order, but from the third file is where calculations begin
(the reason because I put i=3:29, I don't know if it is the correct way)
The original name of the file is so long and just change in the numbers:
1.A2019033.L3m_DAY_CHL.x_chlor_a.nc
2.A2019035.L3m_DAY_CHL.x_chlor_a.nc
3.A2019036.L3m_DAY_CHL.x_chlor_a.nc
4.A2019037.L3m_DAY_CHL.x_chlor_a.nc
The same for the following 27 days.
Probably here I made another mistake with the module %s
I would like to upload the files but they are really big (each day 6MB more and less)
I really aprecciate your help and your comments.
Thanks.
Chris.
@chrismike06, the problem in the call to sprintf is that you changed x to i at the top (i.e., function(i), so now there's no x to find. Change either the i to an x or vice versa and at least that part should work.
Oh, and now I also see what you're saying about the numbers. So, instead of seq(27), you'll need a vector of the numbers in your actual file names (035, 036, etc.). If the leading zero is always there, then you can do A20190%s and then use c(33:60) or whatever. If the leading zero switches to a 1 or it's not a straight sequence, you'll need to figure out a different way to create the vector of substrings to paste in with sprintf. All that function does is insert a string into another string, here x into the name, where %s is.
Also, if you use map_dfc, you don't need the do.call bit at the end. That concatenation is built into map_dfc. You only need that if you use lapply, which returns a list.
@ulfelder good news!
Understand your explanation about the string and now the code run!
Although in a rustic mode it code works, is always welcome a new method for improving how to write codes, especially if after you want to reply with more data (This is really common in Ocean techniques where we work with a bunch of files)
Thanks so much for your soon reply!
Greetings!
Here the last modification and the solution.
loop_list <- map_dfc(c(33:59),function(i){
require(oce)
require(ncdf4)
filename <- sprintf("images/february/modis2019/A20190%s.L3m_DAY_CHL.x_chlor_a.nc",i)
vart <- nc_open(filename)
ray <- ncvar_get(ncin,"degrees")
nc_close(vart)
final <- ray[c(ocean)]
return(final)
})