I have some raster files which names are Band_2..., Band_3... etc. I want to order them from the minimum number (2) to the maximum (12). Here is the code I am using

S2_masked<- list.files(S2_masked, full.names = TRUE, pattern = ".tif$")
split <- strsplit(S2_masked, "Band_") 
split <- as.numeric(sapply(split, function(x) x <- sub(".tif", "", x[2])))
S2_masked <- S2_masked[order(split)]
S2_masked<-lapply(1:length(S2_masked), function (x) {raster(S2_masked[x])}) 

I am re-using this code from another project and it used to work but now the output of:

split <- as.numeric(sapply(split, function(x) x <- sub(".tif", "", x[2])))


> split

Not sure what I am missing.

Any idea?

EDIT -----

So here are the output of S2_masked (line 2) and split (line 3)

> S2_masked
 [1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_11_2016_04_22.tif"
 [2] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_12_2016_04_22.tif"
 [3] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_2_2016_04_22.tif" 
 [4] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_3_2016_04_22.tif" 
 [5] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_4_2016_04_22.tif" 
 [6] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_5_2016_04_22.tif" 
 [7] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_6_2016_04_22.tif" 
 [8] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_7_2016_04_22.tif" 
 [9] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_8_2016_04_22.tif" 
[10] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/Band_8A_2016_04_22.tif"

> split
[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "11_2016_04_22.tif"                                                   

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "12_2016_04_22.tif"                                                   

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "2_2016_04_22.tif"                                                    

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "3_2016_04_22.tif"                                                    

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "4_2016_04_22.tif"                                                    

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "5_2016_04_22.tif"                                                    

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "6_2016_04_22.tif"                                                    

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "7_2016_04_22.tif"                                                    

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "8_2016_04_22.tif"                                                    

[1] "/Users/Miguel/Documents/Paper/4_S2_image/2_1_R_Processed/2016_04_22/"
[2] "8A_2016_04_22.tif" 

EDIT 2 ----

Just found the solution, in case it helps someone else:

Following the advice of @spacedman, I manage to get the number after ¨Band_¨in a different way. This is the number I want to use as reference to order my data so,

In line 3 of the code, instead of using ¨Band_¨as element to split the data, I selected ¨_¨.

 [1] "/Users/Miguel/Documents/Paper/4" "S2"                             
 [3] "image/2"                         "1"                              
 [5] "R"                               "Processed/2016"                 
 [7] "04"                              "22/Band"                        
 [9] "8"                               "2016"                                 
[11] "04"                              "22.tif"                         

In that way I end up isolating the number. Then in line 4, I use [9] instead of the previous [2].

After that, the code works and import the data the way I want

closed as unclear what you're asking by Spacedman, lynxlynxlynx, whyzar, John Powell, tinlyx Aug 31 '17 at 13:29

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    Can you show us the actual names of the files you are trying to read? Perhaps list the contents of that folder? Does your S2_masked look okay? Does the first split (line 3) look okay? – Spacedman Aug 31 '17 at 7:14
  • 1
    If I make a bunch of files called Band_2.tif to Band_12.tif in a folder then your code works as expected, so it must be something you're not telling us. – Spacedman Aug 31 '17 at 7:22
  • I just edited the question to show you the output of my intermediate steps. Thanks for your help – GCGM Aug 31 '17 at 7:24
  • 1
    Just a note - it is not advisable to give variables names of existing functions, in this case split. – Janina Aug 31 '17 at 7:26
  • @janina you are completely right, did not realise about that. – GCGM Aug 31 '17 at 7:30

I found a bit of time to look at your question. Here is a somewhat cleaner solution.


S2_masked <- "/2_1_R_Processed/2016_04_22"
S2_masked <- list.files(S2_masked, full.names = TRUE, pattern = ".tif$")
bands <- as.numeric(sapply(S2_masked, function(x) x <- gsub("(Band_)(.*?)(_.*)", "\\2", basename(x))))
S2_masked <- S2_masked[order(bands)]
S2_masked<-lapply(1:length(S2_masked), function (x) {raster(S2_masked[x])})

If you look at the result of sapply you'll see its getting all the part of the name with what looks like the date as well (I made two sample files):

> sapply(split, function(x) x <- sub(".tif", "", x[2]))
[1] "1_2016_14_22" "6_2016_04_22"

which goes to NA when converted to numeric:

> as.numeric(sapply(split, function(x) x <- sub(".tif", "", x[2])))
[1] NA NA

because the code is stripping off everything before Band_ and everything after .tif.

You need a different way of getting the number after Band_, suspect the solution is to use regexec. (No time now for me to do this).

  • Thanks for your reply. Although I understand the problem, I am not sure how to use regexec to solve it – GCGM Aug 31 '17 at 7:46
  • 1
    @GCGM You can try this on the full name: gsub("(Band_)(.*?)(_.*)", "\\2", x[2]) But (!) the raster with the name "Band_8A_2016_04_22.tif" will cause the same problem once again since there is a non-numeric character. – Janina Aug 31 '17 at 8:12
  • Thanks for all your comments and suggestions. I manage to solve the issue. I edited the question again to add the solution for future readers – GCGM Aug 31 '17 at 8:15
  • @Janina, you are right the 8A raster cause a problem but it is sent to the final position of the list, which is fine for my purpose. – GCGM Aug 31 '17 at 8:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.